mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
applemedia-nonpublic: remove bitrotten plugin that's no longer needed
This commit is contained in:
parent
6de83e0515
commit
c8321a3173
31 changed files with 2 additions and 5919 deletions
|
@ -3704,7 +3704,6 @@ sys/acmenc/Makefile
|
|||
sys/acmmp3dec/Makefile
|
||||
sys/androidmedia/Makefile
|
||||
sys/applemedia/Makefile
|
||||
sys/applemedia-nonpublic/Makefile
|
||||
sys/avc/Makefile
|
||||
sys/bluez/Makefile
|
||||
sys/d3dvideosink/Makefile
|
||||
|
|
|
@ -11,7 +11,7 @@ ANDROID_MEDIA_DIR=
|
|||
endif
|
||||
|
||||
if USE_APPLE_MEDIA
|
||||
APPLE_MEDIA_DIR=applemedia applemedia-nonpublic
|
||||
APPLE_MEDIA_DIR=applemedia
|
||||
else
|
||||
APPLE_MEDIA_DIR=
|
||||
endif
|
||||
|
@ -156,7 +156,7 @@ endif
|
|||
|
||||
SUBDIRS = $(ACM_DIR) $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(AVC_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(KMS_DIR) $(LINSYS_DIR) $(OPENSLES_DIR) $(PVR_DIR) $(SHM_DIR) $(UVCH264_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR) $(NVENC_DIR) $(TINYALSA_DIR)
|
||||
|
||||
DIST_SUBDIRS = acmenc acmmp3dec androidmedia applemedia applemedia-nonpublic avc bluez d3dvideosink decklink directsound dvb linsys fbdev kms dshowdecwrapper dshowsrcwrapper dshowvideosink \
|
||||
DIST_SUBDIRS = acmenc acmmp3dec androidmedia applemedia avc bluez d3dvideosink decklink directsound dvb linsys fbdev kms dshowdecwrapper dshowsrcwrapper dshowvideosink \
|
||||
opensles pvr2d shm uvch264 vcd vdpau wasapi wininet winks winscreencap \
|
||||
nvenc tinyalsa
|
||||
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
plugin_LTLIBRARIES = libgstapplemedia_nonpublic.la
|
||||
|
||||
libgstapplemedia_nonpublic_la_SOURCES = \
|
||||
plugin.m \
|
||||
bufferfactory.m \
|
||||
corevideobuffer.c \
|
||||
coremediabuffer.c \
|
||||
cvapi.c \
|
||||
cmapi.c \
|
||||
coremediactx.c \
|
||||
dynapi.c
|
||||
|
||||
libgstapplemedia_nonpublic_la_CPPFLAGS = \
|
||||
-Dgst_dyn_api_get_type=gst_dyn_api_priv_get_type \
|
||||
-Dgst_dyn_api_debug=gst_dyn_api_priv_debug \
|
||||
-Dgst_dyn_api_new=gst_dyn_api_priv_new \
|
||||
-Dgst_core_media_buffer_new=gst_core_media_buffer_priv_new \
|
||||
-Dgst_core_media_buffer_get_type=gst_core_media_buffer_priv_get_type \
|
||||
-Dgst_core_media_buffer_get_pixel_buffer=gst_core_media_buffer_priv_get_pixel_buffer\
|
||||
-Dgst_core_video_buffer_new=gst_core_video_buffer_priv_new \
|
||||
-Dgst_core_video_buffer_get_type=gst_core_video_buffer_priv_get_type \
|
||||
-Dgst_core_media_ctx_new=gst_core_media_ctx_priv_new \
|
||||
-Dgst_core_media_ctx_get_type=gst_core_media_ctx_priv_get_type
|
||||
|
||||
libgstapplemedia_nonpublic_la_CFLAGS = \
|
||||
$(GST_CFLAGS) \
|
||||
$(GST_BASE_CFLAGS) \
|
||||
$(GST_PLUGINS_BASE_CFLAGS)
|
||||
|
||||
libgstapplemedia_nonpublic_la_OBJCFLAGS = \
|
||||
$(GST_OBJCFLAGS) \
|
||||
$(GST_BASE_CFLAGS) \
|
||||
$(GST_PLUGINS_BASE_CFLAGS)
|
||||
|
||||
if HAVE_IOS
|
||||
libgstapplemedia_nonpublic_la_OBJCFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
|
||||
endif
|
||||
|
||||
libgstapplemedia_nonpublic_la_LIBADD = \
|
||||
$(GST_BASE_LIBS) \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
-lgstvideo-$(GST_API_VERSION) \
|
||||
$(GMODULE_NO_EXPORT_LIBS)
|
||||
|
||||
libgstapplemedia_nonpublic_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) --tag=CC
|
||||
|
||||
libgstapplemedia_nonpublic_la_LDFLAGS = \
|
||||
$(GST_PLUGIN_LDFLAGS) \
|
||||
$(GST_BASE_LDFLAGS) \
|
||||
$(GST_PLUGINS_BASE_LDFLAGS) \
|
||||
-Wl,-framework -Wl,Foundation \
|
||||
-Wl,-framework -Wl,CoreFoundation \
|
||||
-Wl,-framework -Wl,CoreVideo
|
||||
|
||||
noinst_HEADERS = \
|
||||
miovideosrc.h \
|
||||
miovideodevice.h \
|
||||
celvideosrc.h \
|
||||
bufferfactory.h \
|
||||
corevideobuffer.h \
|
||||
coremediabuffer.h \
|
||||
coremediactx.h \
|
||||
mioapi.h \
|
||||
mtapi.h \
|
||||
celapi.h \
|
||||
cvapi.h \
|
||||
cmapi.h \
|
||||
dynapi.h \
|
||||
dynapi-internal.h
|
||||
|
||||
if HAVE_IOS
|
||||
|
||||
#libgstapplemedia_nonpublic_la_SOURCES += \
|
||||
# celvideosrc.c \
|
||||
# mtapi.c \
|
||||
# celapi.c
|
||||
|
||||
else
|
||||
|
||||
libgstapplemedia_nonpublic_la_SOURCES += \
|
||||
mioapi.c
|
||||
|
||||
endif
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
@interface GstAMBufferFactory : NSObject {
|
||||
gpointer coreMediaCtx;
|
||||
}
|
||||
|
||||
- (id)initWithError:(GError **)error;
|
||||
- (void)finalize;
|
||||
|
||||
- (GstBuffer *)createGstBufferForCoreVideoBuffer:(CFTypeRef)cvbuf;
|
||||
- (GstBuffer *)createGstBufferForSampleBuffer:(CFTypeRef)sbuf;
|
||||
|
||||
@end
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "bufferfactory.h"
|
||||
|
||||
#include "coremediabuffer.h"
|
||||
#include "corevideobuffer.h"
|
||||
|
||||
@implementation GstAMBufferFactory
|
||||
|
||||
- (id)initWithError:(GError **)error
|
||||
{
|
||||
GstCoreMediaCtx *ctx;
|
||||
|
||||
ctx =
|
||||
gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA, error);
|
||||
if (ctx == NULL)
|
||||
return nil;
|
||||
|
||||
if ((self = [super init]))
|
||||
coreMediaCtx = ctx;
|
||||
else
|
||||
g_object_unref (ctx);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)finalize
|
||||
{
|
||||
g_object_unref (coreMediaCtx);
|
||||
|
||||
[super finalize];
|
||||
}
|
||||
|
||||
- (GstBuffer *)createGstBufferForCoreVideoBuffer:(CFTypeRef)cvbuf
|
||||
{
|
||||
return gst_core_video_buffer_new (coreMediaCtx, (CVBufferRef) cvbuf, NULL);
|
||||
}
|
||||
|
||||
- (GstBuffer *)createGstBufferForSampleBuffer:(CFTypeRef)sbuf
|
||||
{
|
||||
return gst_core_media_buffer_new (coreMediaCtx, sbuf);
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "celapi.h"
|
||||
|
||||
#include "dynapi-internal.h"
|
||||
|
||||
#define CELESTIAL_FRAMEWORK_PATH "/System/Library/PrivateFrameworks/" \
|
||||
"Celestial.framework/Celestial"
|
||||
|
||||
G_DEFINE_TYPE (GstCelApi, gst_cel_api, GST_TYPE_DYN_API);
|
||||
|
||||
static void
|
||||
gst_cel_api_init (GstCelApi * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_api_class_init (GstCelApiClass * klass)
|
||||
{
|
||||
}
|
||||
|
||||
#define SYM_SPEC(name) GST_DYN_SYM_SPEC (GstCelApi, name)
|
||||
|
||||
GstCelApi *
|
||||
gst_cel_api_obtain (GError ** error)
|
||||
{
|
||||
static const GstDynSymSpec symbols[] = {
|
||||
SYM_SPEC (FigCreateCaptureDevicesAndStreamsForPreset),
|
||||
|
||||
SYM_SPEC (kFigCaptureDeviceProperty_MultiplexStreams),
|
||||
SYM_SPEC (kFigCapturePortType_Bottom),
|
||||
SYM_SPEC (kFigCapturePortType_Camera),
|
||||
SYM_SPEC (kFigCapturePortType_FrontFacingCamera),
|
||||
SYM_SPEC (kFigCapturePortType_Top),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFEarlyOutAllowPeakAtStart),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFEarlyOutDecrementAmount),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFEarlyOutEnable),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFEarlyOutThreshold),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFPositionCurrent),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFPositionInfinity),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFPositionMacro),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AFSearchPositionArray),
|
||||
SYM_SPEC (kFigCapturePropertyValue_AGC),
|
||||
SYM_SPEC (kFigCapturePropertyValue_CLPFControl),
|
||||
SYM_SPEC (kFigCapturePropertyValue_ColorRangeFull),
|
||||
SYM_SPEC (kFigCapturePropertyValue_ColorRangeSDVideo),
|
||||
SYM_SPEC (kFigCapturePropertyValue_ModuleDate),
|
||||
SYM_SPEC (kFigCapturePropertyValue_ModuleIntegratorInfo),
|
||||
SYM_SPEC (kFigCapturePropertyValue_SensorID),
|
||||
SYM_SPEC (kFigCapturePropertyValue_SigmaFilterControl),
|
||||
SYM_SPEC (kFigCapturePropertyValue_YLPFControl),
|
||||
SYM_SPEC (kFigCapturePropertyValue_hStart),
|
||||
SYM_SPEC (kFigCapturePropertyValue_height),
|
||||
SYM_SPEC (kFigCapturePropertyValue_ispDGain),
|
||||
SYM_SPEC (kFigCapturePropertyValue_sensorDGain),
|
||||
SYM_SPEC (kFigCapturePropertyValue_shutterSpeedDenominator),
|
||||
SYM_SPEC (kFigCapturePropertyValue_shutterSpeedNumerator),
|
||||
SYM_SPEC (kFigCapturePropertyValue_vStart),
|
||||
SYM_SPEC (kFigCapturePropertyValue_weight),
|
||||
SYM_SPEC (kFigCapturePropertyValue_width),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_AEBracketedCaptureParams),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_BLCCompensation),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_BLCDebugMode),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_BandHighFactor),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_BandLowFactor),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_CCMWarmUpWeight),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EdgeColorSuppressionSlope),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EdgeColorSuppressionThreshold),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EnableAESceneDynamicMetering),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EnableCCMWarmUp),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EnableHistogram1MetaData),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EnableHistogram2MetaData),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EnableHistogram3MetaData),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EnableHistogram4MetaData),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_EnableHistogram),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_HistogramBinMode),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_HistogramDataType),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_ImageCropRect),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_LPExposure),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_LPGain),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_LowWeight),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_MaxWeight),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_MediumWeight),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_MinWeight),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_WeightDropOff),
|
||||
SYM_SPEC (kFigCaptureStreamPropertyValue_WeightReduction),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AEConvergenceSpeed),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AEOutlierClipCount),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AESceneDynamicMetering),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AEStability),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AEWindowManualWeightMatrix),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AEWindowParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AFEarlyOutParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AFParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AFSearchPositions),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AFWindowParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AGC),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AWBWindowParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AdditionalPTSOffset),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AlternateAWB),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_Apply3AWindowSettings),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AttachRAW),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_CCMWarmUp),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ClientMaxBufferCountHint),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ColorRange),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ColorSaturation),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ColorTables),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_EdgeColorSuppressionParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ExposureBias),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_FastSwitchMode),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_FlashMode),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_HistogramParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_LockAENow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_LockAWBNow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ManualAENow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ManualFocusNow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_MaxIntegrationTime),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ModuleInfo),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_NoiseReductionControls),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_PortType),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_PreFrameAE),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_RawImageProcessNow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_RedEyeReductionParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ResetParams),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_ScalerSharpening),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_SetGainCap),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_SharpeningControl),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_TorchLevel),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_UnlockAENow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_UnlockAWBNow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_UseFlashAFAssist),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_UseFlashRedEyeReduction),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_UseHardwareShutter),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_VideoRecordingInProgress),
|
||||
SYM_SPEC (kFigRecorderCapturePreset_AudioRecording),
|
||||
SYM_SPEC (kFigRecorderCapturePreset_AudioVideoRecording),
|
||||
SYM_SPEC (kFigRecorderCapturePreset_PhotoCapture),
|
||||
SYM_SPEC (kFigRecorderCapturePreset_VideoRecording),
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
return _gst_dyn_api_new (gst_cel_api_get_type (), CELESTIAL_FRAMEWORK_PATH,
|
||||
symbols, error);
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_CEL_API_H__
|
||||
#define __GST_CEL_API_H__
|
||||
|
||||
#include "mtapi.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstCelApi GstCelApi;
|
||||
typedef struct _GstCelApiClass GstCelApiClass;
|
||||
|
||||
enum
|
||||
{
|
||||
kCelError_ResourceBusy = -12780
|
||||
};
|
||||
|
||||
struct _GstCelApi
|
||||
{
|
||||
GstDynApi parent;
|
||||
|
||||
OSStatus (* FigCreateCaptureDevicesAndStreamsForPreset)
|
||||
(CFAllocatorRef allocator, CFStringRef capturePreset,
|
||||
CFDictionaryRef audioOptions,
|
||||
FigCaptureDeviceRef * outVideoDevice,
|
||||
FigCaptureStreamRef * outVideoStream,
|
||||
FigCaptureDeviceRef * outAudioDevice,
|
||||
FigCaptureStreamRef * outAudioStream);
|
||||
|
||||
CFStringRef * kFigCaptureDeviceProperty_MultiplexStreams;
|
||||
CFStringRef * kFigCapturePortType_Bottom;
|
||||
CFStringRef * kFigCapturePortType_Camera;
|
||||
CFStringRef * kFigCapturePortType_FrontFacingCamera;
|
||||
CFStringRef * kFigCapturePortType_Top;
|
||||
CFStringRef * kFigCapturePropertyValue_AFEarlyOutAllowPeakAtStart;
|
||||
CFStringRef * kFigCapturePropertyValue_AFEarlyOutDecrementAmount;
|
||||
CFStringRef * kFigCapturePropertyValue_AFEarlyOutEnable;
|
||||
CFStringRef * kFigCapturePropertyValue_AFEarlyOutThreshold;
|
||||
CFStringRef * kFigCapturePropertyValue_AFPositionCurrent;
|
||||
CFStringRef * kFigCapturePropertyValue_AFPositionInfinity;
|
||||
CFStringRef * kFigCapturePropertyValue_AFPositionMacro;
|
||||
CFStringRef * kFigCapturePropertyValue_AFSearchPositionArray;
|
||||
CFStringRef * kFigCapturePropertyValue_AGC;
|
||||
CFStringRef * kFigCapturePropertyValue_CLPFControl;
|
||||
CFStringRef * kFigCapturePropertyValue_ColorRangeFull;
|
||||
CFStringRef * kFigCapturePropertyValue_ColorRangeSDVideo;
|
||||
CFStringRef * kFigCapturePropertyValue_ModuleDate;
|
||||
CFStringRef * kFigCapturePropertyValue_ModuleIntegratorInfo;
|
||||
CFStringRef * kFigCapturePropertyValue_SensorID;
|
||||
CFStringRef * kFigCapturePropertyValue_SigmaFilterControl;
|
||||
CFStringRef * kFigCapturePropertyValue_YLPFControl;
|
||||
CFStringRef * kFigCapturePropertyValue_hStart;
|
||||
CFStringRef * kFigCapturePropertyValue_height;
|
||||
CFStringRef * kFigCapturePropertyValue_ispDGain;
|
||||
CFStringRef * kFigCapturePropertyValue_sensorDGain;
|
||||
CFStringRef * kFigCapturePropertyValue_shutterSpeedDenominator;
|
||||
CFStringRef * kFigCapturePropertyValue_shutterSpeedNumerator;
|
||||
CFStringRef * kFigCapturePropertyValue_vStart;
|
||||
CFStringRef * kFigCapturePropertyValue_weight;
|
||||
CFStringRef * kFigCapturePropertyValue_width;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_AEBracketedCaptureParams;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_BLCCompensation;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_BLCDebugMode;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_BandHighFactor;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_BandLowFactor;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_CCMWarmUpWeight;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EdgeColorSuppressionSlope;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EdgeColorSuppressionThreshold;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EnableAESceneDynamicMetering;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EnableCCMWarmUp;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EnableHistogram1MetaData;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EnableHistogram2MetaData;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EnableHistogram3MetaData;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EnableHistogram4MetaData;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_EnableHistogram;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_HistogramBinMode;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_HistogramDataType;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_ImageCropRect;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_LPExposure;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_LPGain;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_LowWeight;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_MaxWeight;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_MediumWeight;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_MinWeight;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_WeightDropOff;
|
||||
CFStringRef * kFigCaptureStreamPropertyValue_WeightReduction;
|
||||
CFStringRef * kFigCaptureStreamProperty_AEConvergenceSpeed;
|
||||
CFStringRef * kFigCaptureStreamProperty_AEOutlierClipCount;
|
||||
CFStringRef * kFigCaptureStreamProperty_AESceneDynamicMetering;
|
||||
CFStringRef * kFigCaptureStreamProperty_AEStability;
|
||||
CFStringRef * kFigCaptureStreamProperty_AEWindowManualWeightMatrix;
|
||||
CFStringRef * kFigCaptureStreamProperty_AEWindowParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_AFEarlyOutParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_AFParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_AFSearchPositions;
|
||||
CFStringRef * kFigCaptureStreamProperty_AFWindowParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_AGC;
|
||||
CFStringRef * kFigCaptureStreamProperty_AWBWindowParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_AdditionalPTSOffset;
|
||||
CFStringRef * kFigCaptureStreamProperty_AlternateAWB;
|
||||
CFStringRef * kFigCaptureStreamProperty_Apply3AWindowSettings;
|
||||
CFStringRef * kFigCaptureStreamProperty_AttachRAW;
|
||||
CFStringRef * kFigCaptureStreamProperty_CCMWarmUp;
|
||||
CFStringRef * kFigCaptureStreamProperty_ClientMaxBufferCountHint;
|
||||
CFStringRef * kFigCaptureStreamProperty_ColorRange;
|
||||
CFStringRef * kFigCaptureStreamProperty_ColorSaturation;
|
||||
CFStringRef * kFigCaptureStreamProperty_ColorTables;
|
||||
CFStringRef * kFigCaptureStreamProperty_EdgeColorSuppressionParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_ExposureBias;
|
||||
CFStringRef * kFigCaptureStreamProperty_FastSwitchMode;
|
||||
CFStringRef * kFigCaptureStreamProperty_FlashMode;
|
||||
CFStringRef * kFigCaptureStreamProperty_HistogramParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_LockAENow;
|
||||
CFStringRef * kFigCaptureStreamProperty_LockAWBNow;
|
||||
CFStringRef * kFigCaptureStreamProperty_ManualAENow;
|
||||
CFStringRef * kFigCaptureStreamProperty_ManualFocusNow;
|
||||
CFStringRef * kFigCaptureStreamProperty_MaxIntegrationTime;
|
||||
CFStringRef * kFigCaptureStreamProperty_ModuleInfo;
|
||||
CFStringRef * kFigCaptureStreamProperty_NoiseReductionControls;
|
||||
CFStringRef * kFigCaptureStreamProperty_PortType;
|
||||
CFStringRef * kFigCaptureStreamProperty_PreFrameAE;
|
||||
CFStringRef * kFigCaptureStreamProperty_RawImageProcessNow;
|
||||
CFStringRef * kFigCaptureStreamProperty_RedEyeReductionParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_ResetParams;
|
||||
CFStringRef * kFigCaptureStreamProperty_ScalerSharpening;
|
||||
CFStringRef * kFigCaptureStreamProperty_SetGainCap;
|
||||
CFStringRef * kFigCaptureStreamProperty_SharpeningControl;
|
||||
CFStringRef * kFigCaptureStreamProperty_TorchLevel;
|
||||
CFStringRef * kFigCaptureStreamProperty_UnlockAENow;
|
||||
CFStringRef * kFigCaptureStreamProperty_UnlockAWBNow;
|
||||
CFStringRef * kFigCaptureStreamProperty_UseFlashAFAssist;
|
||||
CFStringRef * kFigCaptureStreamProperty_UseFlashRedEyeReduction;
|
||||
CFStringRef * kFigCaptureStreamProperty_UseHardwareShutter;
|
||||
CFStringRef * kFigCaptureStreamProperty_VideoRecordingInProgress;
|
||||
CFStringRef * kFigRecorderCapturePreset_AudioRecording;
|
||||
CFStringRef * kFigRecorderCapturePreset_AudioVideoRecording;
|
||||
CFStringRef * kFigRecorderCapturePreset_PhotoCapture;
|
||||
CFStringRef * kFigRecorderCapturePreset_VideoRecording;
|
||||
};
|
||||
|
||||
struct _GstCelApiClass
|
||||
{
|
||||
GstDynApiClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_cel_api_get_type (void);
|
||||
|
||||
GstCelApi * gst_cel_api_obtain (GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,880 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "celvideosrc.h"
|
||||
|
||||
#include "coremediabuffer.h"
|
||||
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#define DEFAULT_DEVICE_INDEX -1
|
||||
#define DEFAULT_DO_STATS FALSE
|
||||
|
||||
#define QUEUE_READY_LOCK(instance) GST_OBJECT_LOCK (instance)
|
||||
#define QUEUE_READY_UNLOCK(instance) GST_OBJECT_UNLOCK (instance)
|
||||
#define QUEUE_READY_WAIT(instance) \
|
||||
g_cond_wait (instance->ready_cond, GST_OBJECT_GET_LOCK (instance))
|
||||
#define QUEUE_READY_NOTIFY(instance) g_cond_signal (instance->ready_cond)
|
||||
|
||||
GST_DEBUG_CATEGORY (gst_cel_video_src_debug);
|
||||
#define GST_CAT_DEFAULT gst_cel_video_src_debug
|
||||
|
||||
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12") ";"
|
||||
GST_VIDEO_CAPS_YUV ("YUY2"))
|
||||
);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_DEVICE_INDEX,
|
||||
PROP_DO_STATS,
|
||||
PROP_FPS
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint index;
|
||||
|
||||
GstVideoFormat video_format;
|
||||
guint32 fourcc;
|
||||
gint width;
|
||||
gint height;
|
||||
gint fps_n;
|
||||
gint fps_d;
|
||||
} GstCelVideoFormat;
|
||||
|
||||
static gboolean gst_cel_video_src_open_device (GstCelVideoSrc * self);
|
||||
static void gst_cel_video_src_close_device (GstCelVideoSrc * self);
|
||||
static void gst_cel_video_src_ensure_device_caps_and_formats
|
||||
(GstCelVideoSrc * self);
|
||||
static void gst_cel_video_src_release_device_caps_and_formats
|
||||
(GstCelVideoSrc * self);
|
||||
static gboolean gst_cel_video_src_select_format (GstCelVideoSrc * self,
|
||||
GstCelVideoFormat * format);
|
||||
|
||||
static gboolean gst_cel_video_src_parse_stream_format
|
||||
(GstCelVideoSrc * self, guint index, CFDictionaryRef stream_format,
|
||||
GstCelVideoFormat * format);
|
||||
static OSStatus gst_cel_video_src_set_stream_property_i32
|
||||
(GstCelVideoSrc * self, CFStringRef name, SInt32 value);
|
||||
static OSStatus gst_cel_video_src_set_stream_property_value
|
||||
(GstCelVideoSrc * self, CFStringRef name, CFTypeRef value);
|
||||
|
||||
static GstPushSrcClass *parent_class;
|
||||
|
||||
GST_BOILERPLATE (GstCelVideoSrc, gst_cel_video_src, GstPushSrc,
|
||||
GST_TYPE_PUSH_SRC);
|
||||
|
||||
static void
|
||||
gst_cel_video_src_init (GstCelVideoSrc * self, GstCelVideoSrcClass * gclass)
|
||||
{
|
||||
GstBaseSrc *base_src = GST_BASE_SRC_CAST (self);
|
||||
|
||||
gst_base_src_set_live (base_src, TRUE);
|
||||
gst_base_src_set_format (base_src, GST_FORMAT_TIME);
|
||||
|
||||
self->ready_cond = g_cond_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_dispose (GObject * object)
|
||||
{
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_finalize (GObject * object)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (object);
|
||||
|
||||
g_cond_free (self->ready_cond);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE_INDEX:
|
||||
g_value_set_int (value, self->device_index);
|
||||
break;
|
||||
case PROP_DO_STATS:
|
||||
g_value_set_boolean (value, self->do_stats);
|
||||
break;
|
||||
case PROP_FPS:
|
||||
GST_OBJECT_LOCK (object);
|
||||
g_value_set_int (value, self->fps);
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE_INDEX:
|
||||
self->device_index = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_DO_STATS:
|
||||
self->do_stats = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_cel_video_src_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (element);
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
if (!gst_cel_video_src_open_device (self))
|
||||
goto open_failed;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
gst_cel_video_src_close_device (self);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
open_failed:
|
||||
{
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_cel_video_src_get_caps (GstBaseSrc * basesrc)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
|
||||
GstCaps *result;
|
||||
|
||||
if (self->device != NULL) {
|
||||
gst_cel_video_src_ensure_device_caps_and_formats (self);
|
||||
|
||||
result = gst_caps_ref (self->device_caps);
|
||||
} else {
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
if (result != NULL) {
|
||||
gchar *str;
|
||||
|
||||
str = gst_caps_to_string (result);
|
||||
GST_DEBUG_OBJECT (self, "returning: %s", str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
|
||||
GstVideoFormat video_format;
|
||||
gint width, height, fps_n, fps_d;
|
||||
guint i;
|
||||
GstCelVideoFormat *selected_format;
|
||||
|
||||
if (self->device == NULL)
|
||||
goto no_device;
|
||||
|
||||
if (!gst_video_format_parse_caps (caps, &video_format, &width, &height))
|
||||
goto invalid_format;
|
||||
if (!gst_video_parse_caps_framerate (caps, &fps_n, &fps_d))
|
||||
goto invalid_format;
|
||||
|
||||
gst_cel_video_src_ensure_device_caps_and_formats (self);
|
||||
|
||||
selected_format = NULL;
|
||||
|
||||
for (i = 0; i != self->device_formats->len; i++) {
|
||||
GstCelVideoFormat *format;
|
||||
|
||||
format = &g_array_index (self->device_formats, GstCelVideoFormat, i);
|
||||
if (format->video_format == video_format &&
|
||||
format->width == width && format->height == height &&
|
||||
format->fps_n == fps_n && format->fps_d == fps_d) {
|
||||
selected_format = format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected_format == NULL)
|
||||
goto invalid_format;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "selecting format %u", selected_format->index);
|
||||
|
||||
if (!gst_cel_video_src_select_format (self, selected_format))
|
||||
goto select_failed;
|
||||
|
||||
gst_cel_video_src_release_device_caps_and_formats (self);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_device:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("no device"), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
invalid_format:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("invalid format"), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
select_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("failed to select format"),
|
||||
(NULL));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_start (GstBaseSrc * basesrc)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
|
||||
|
||||
g_atomic_int_set (&self->is_running, TRUE);
|
||||
self->offset = 0;
|
||||
|
||||
self->last_sampling = GST_CLOCK_TIME_NONE;
|
||||
self->count = 0;
|
||||
self->fps = -1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_stop (GstBaseSrc * basesrc)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_query (GstBaseSrc * basesrc, GstQuery * query)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
|
||||
gboolean result = FALSE;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_LATENCY:{
|
||||
GstClockTime min_latency, max_latency;
|
||||
|
||||
if (self->device == NULL || !GST_CLOCK_TIME_IS_VALID (self->duration))
|
||||
goto beach;
|
||||
|
||||
min_latency = max_latency = self->duration;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "reporting latency of min %" GST_TIME_FORMAT
|
||||
" max %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
|
||||
|
||||
gst_query_set_latency (query, TRUE, min_latency, max_latency);
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
|
||||
break;
|
||||
}
|
||||
|
||||
beach:
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_unlock (GstBaseSrc * basesrc)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc);
|
||||
|
||||
g_atomic_int_set (&self->is_running, FALSE);
|
||||
|
||||
QUEUE_READY_LOCK (self);
|
||||
QUEUE_READY_NOTIFY (self);
|
||||
QUEUE_READY_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_unlock_stop (GstBaseSrc * basesrc)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_on_queue_ready (void *triggerRefcon,
|
||||
CMBufferQueueTriggerToken triggerToken)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (triggerRefcon);
|
||||
|
||||
QUEUE_READY_LOCK (self);
|
||||
self->queue_is_ready = TRUE;
|
||||
QUEUE_READY_NOTIFY (self);
|
||||
QUEUE_READY_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_timestamp_buffer (GstCelVideoSrc * self, GstBuffer * buf)
|
||||
{
|
||||
GstClock *clock;
|
||||
GstClockTime ts;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
if ((clock = GST_ELEMENT_CLOCK (self)) != NULL) {
|
||||
ts = gst_clock_get_time (clock);
|
||||
|
||||
if (ts > GST_ELEMENT (self)->base_time)
|
||||
ts -= GST_ELEMENT (self)->base_time;
|
||||
else
|
||||
ts = 0;
|
||||
|
||||
if (ts > self->duration)
|
||||
ts -= self->duration;
|
||||
else
|
||||
ts = 0;
|
||||
} else {
|
||||
ts = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
GST_BUFFER_OFFSET (buf) = self->offset;
|
||||
GST_BUFFER_OFFSET_END (buf) = self->offset + 1;
|
||||
GST_BUFFER_TIMESTAMP (buf) = ts;
|
||||
GST_BUFFER_DURATION (buf) = self->duration;
|
||||
|
||||
if (self->offset == 0)
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||
|
||||
self->offset++;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_update_statistics (GstCelVideoSrc * self)
|
||||
{
|
||||
GstClock *clock;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
clock = GST_ELEMENT_CLOCK (self);
|
||||
if (clock != NULL)
|
||||
gst_object_ref (clock);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
if (clock != NULL) {
|
||||
GstClockTime now = gst_clock_get_time (clock);
|
||||
gst_object_unref (clock);
|
||||
|
||||
self->count++;
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (self->last_sampling)) {
|
||||
if (now - self->last_sampling >= GST_SECOND) {
|
||||
GST_OBJECT_LOCK (self);
|
||||
self->fps = self->count;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
g_object_notify (G_OBJECT (self), "fps");
|
||||
|
||||
self->last_sampling = now;
|
||||
self->count = 0;
|
||||
}
|
||||
} else {
|
||||
self->last_sampling = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_cel_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf)
|
||||
{
|
||||
GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (pushsrc);
|
||||
GstCMApi *cm = self->ctx->cm;
|
||||
CMSampleBufferRef sbuf;
|
||||
|
||||
sbuf = cm->CMBufferQueueDequeueAndRetain (self->queue);
|
||||
|
||||
while (sbuf == NULL) {
|
||||
QUEUE_READY_LOCK (self);
|
||||
while (!self->queue_is_ready && g_atomic_int_get (&self->is_running))
|
||||
QUEUE_READY_WAIT (self);
|
||||
self->queue_is_ready = FALSE;
|
||||
QUEUE_READY_UNLOCK (self);
|
||||
|
||||
if (G_UNLIKELY (!g_atomic_int_get (&self->is_running)))
|
||||
goto shutting_down;
|
||||
|
||||
sbuf = cm->CMBufferQueueDequeueAndRetain (self->queue);
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!g_atomic_int_get (&self->is_running)))
|
||||
goto shutting_down;
|
||||
|
||||
*buf = gst_core_media_buffer_new (self->ctx, sbuf);
|
||||
gst_cel_video_src_timestamp_buffer (self, *buf);
|
||||
|
||||
cm->FigSampleBufferRelease (sbuf);
|
||||
|
||||
if (self->do_stats)
|
||||
gst_cel_video_src_update_statistics (self);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
|
||||
/* ERRORS */
|
||||
shutting_down:
|
||||
{
|
||||
cm->FigSampleBufferRelease (sbuf);
|
||||
return GST_FLOW_FLUSHING;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_open_device (GstCelVideoSrc * self)
|
||||
{
|
||||
GstCoreMediaCtx *ctx = NULL;
|
||||
GError *error = NULL;
|
||||
GstCMApi *cm = NULL;
|
||||
GstMTApi *mt = NULL;
|
||||
GstCelApi *cel = NULL;
|
||||
OSStatus status;
|
||||
FigCaptureDeviceRef device = NULL;
|
||||
FigBaseObjectRef device_base;
|
||||
FigBaseVTable *device_vt;
|
||||
CFArrayRef stream_array = NULL;
|
||||
CFIndex stream_index;
|
||||
FigCaptureStreamRef stream = NULL;
|
||||
FigBaseObjectRef stream_base;
|
||||
FigBaseVTable *stream_vt;
|
||||
CMBufferQueueRef queue = NULL;
|
||||
CMTime ignored_time;
|
||||
|
||||
ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
|
||||
| GST_API_MEDIA_TOOLBOX | GST_API_CELESTIAL, &error);
|
||||
if (error != NULL)
|
||||
goto api_error;
|
||||
cm = ctx->cm;
|
||||
mt = ctx->mt;
|
||||
cel = ctx->cel;
|
||||
|
||||
status = cel->FigCreateCaptureDevicesAndStreamsForPreset (NULL,
|
||||
*(cel->kFigRecorderCapturePreset_VideoRecording), NULL,
|
||||
&device, &stream, NULL, NULL);
|
||||
if (status == kCelError_ResourceBusy)
|
||||
goto device_busy;
|
||||
else if (status != noErr)
|
||||
goto unexpected_error;
|
||||
|
||||
device_base = mt->FigCaptureDeviceGetFigBaseObject (device);
|
||||
device_vt = cm->FigBaseObjectGetVTable (device_base);
|
||||
|
||||
status = device_vt->base->CopyProperty (device_base,
|
||||
*(mt->kFigCaptureDeviceProperty_StreamArray), NULL,
|
||||
(CFTypeRef *) & stream_array);
|
||||
if (status != noErr)
|
||||
goto unexpected_error;
|
||||
|
||||
if (self->device_index >= 0)
|
||||
stream_index = self->device_index;
|
||||
else
|
||||
stream_index = 0;
|
||||
|
||||
if (stream_index >= CFArrayGetCount (stream_array))
|
||||
goto invalid_device_index;
|
||||
|
||||
CFRelease (stream);
|
||||
stream = (FigCaptureStreamRef) CFArrayGetValueAtIndex (stream_array,
|
||||
stream_index);
|
||||
CFRetain (stream);
|
||||
|
||||
stream_base = mt->FigCaptureStreamGetFigBaseObject (stream);
|
||||
stream_vt = cm->FigBaseObjectGetVTable (stream_base);
|
||||
|
||||
status = stream_vt->base->CopyProperty (stream_base,
|
||||
*(mt->kFigCaptureStreamProperty_BufferQueue), NULL, &queue);
|
||||
if (status != noErr)
|
||||
goto unexpected_error;
|
||||
|
||||
self->queue_is_ready = FALSE;
|
||||
|
||||
ignored_time = cm->CMTimeMake (1, 1);
|
||||
status = cm->CMBufferQueueInstallTrigger (queue,
|
||||
gst_cel_video_src_on_queue_ready, self,
|
||||
kCMBufferQueueTrigger_WhenDataBecomesReady, ignored_time,
|
||||
&self->ready_trigger);
|
||||
if (status != noErr)
|
||||
goto unexpected_error;
|
||||
|
||||
self->ctx = ctx;
|
||||
|
||||
self->device = device;
|
||||
self->device_iface = device_vt->derived;
|
||||
self->device_base = device_base;
|
||||
self->device_base_iface = device_vt->base;
|
||||
self->stream = stream;
|
||||
self->stream_iface = stream_vt->derived;
|
||||
self->stream_base = stream_base;
|
||||
self->stream_base_iface = stream_vt->base;
|
||||
|
||||
self->queue = queue;
|
||||
self->duration = GST_CLOCK_TIME_NONE;
|
||||
|
||||
CFRelease (stream_array);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
api_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("API error"),
|
||||
("%s", error->message));
|
||||
g_clear_error (&error);
|
||||
goto any_error;
|
||||
}
|
||||
device_busy:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, BUSY,
|
||||
("device is already in use"), (NULL));
|
||||
goto any_error;
|
||||
}
|
||||
invalid_device_index:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
|
||||
("invalid video capture device index"), (NULL));
|
||||
goto any_error;
|
||||
}
|
||||
unexpected_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
|
||||
("unexpected error while opening device (%d)", (gint) status), (NULL));
|
||||
goto any_error;
|
||||
}
|
||||
any_error:
|
||||
{
|
||||
if (stream != NULL)
|
||||
CFRelease (stream);
|
||||
if (stream_array != NULL)
|
||||
CFRelease (stream_array);
|
||||
if (device != NULL)
|
||||
CFRelease (device);
|
||||
|
||||
if (ctx != NULL) {
|
||||
cm->FigBufferQueueRelease (queue);
|
||||
g_object_unref (ctx);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_close_device (GstCelVideoSrc * self)
|
||||
{
|
||||
gst_cel_video_src_release_device_caps_and_formats (self);
|
||||
|
||||
self->stream_iface->Stop (self->stream);
|
||||
self->stream_base_iface->Finalize (self->stream_base);
|
||||
CFRelease (self->stream);
|
||||
self->stream = NULL;
|
||||
self->stream_iface = NULL;
|
||||
self->stream_base = NULL;
|
||||
self->stream_base_iface = NULL;
|
||||
|
||||
self->device_base_iface->Finalize (self->device_base);
|
||||
CFRelease (self->device);
|
||||
self->device = NULL;
|
||||
self->device_iface = NULL;
|
||||
self->device_base = NULL;
|
||||
self->device_base_iface = NULL;
|
||||
|
||||
self->ctx->cm->CMBufferQueueRemoveTrigger (self->queue, self->ready_trigger);
|
||||
self->ctx->cm->FigBufferQueueRelease (self->queue);
|
||||
self->ready_trigger = NULL;
|
||||
self->queue = NULL;
|
||||
|
||||
g_object_unref (self->ctx);
|
||||
self->ctx = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_ensure_device_caps_and_formats (GstCelVideoSrc * self)
|
||||
{
|
||||
OSStatus status;
|
||||
CFArrayRef stream_formats = NULL;
|
||||
CFIndex format_count, i;
|
||||
|
||||
if (self->device_caps != NULL)
|
||||
goto already_probed;
|
||||
|
||||
self->device_caps = gst_caps_new_empty ();
|
||||
self->device_formats = g_array_new (FALSE, FALSE, sizeof (GstCelVideoFormat));
|
||||
|
||||
status = self->stream_base_iface->CopyProperty (self->stream_base,
|
||||
*(self->ctx->mt->kFigCaptureStreamProperty_SupportedFormatsArray),
|
||||
NULL, (CFTypeRef *) & stream_formats);
|
||||
if (status != noErr)
|
||||
goto beach;
|
||||
|
||||
format_count = CFArrayGetCount (stream_formats);
|
||||
GST_DEBUG_OBJECT (self, "device supports %d formats", (gint) format_count);
|
||||
|
||||
for (i = 0; i != format_count; i++) {
|
||||
CFDictionaryRef sformat;
|
||||
GstCelVideoFormat format;
|
||||
|
||||
sformat = CFArrayGetValueAtIndex (stream_formats, i);
|
||||
|
||||
if (gst_cel_video_src_parse_stream_format (self, i, sformat, &format)) {
|
||||
gst_caps_append_structure (self->device_caps,
|
||||
gst_structure_new ("video/x-raw-yuv",
|
||||
"format", GST_TYPE_FOURCC, format.fourcc,
|
||||
"width", G_TYPE_INT, format.width,
|
||||
"height", G_TYPE_INT, format.height,
|
||||
"framerate", GST_TYPE_FRACTION, format.fps_n, format.fps_d,
|
||||
"pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL));
|
||||
g_array_append_val (self->device_formats, format);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (self, "ignoring unknown format #%d", (gint) i);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease (stream_formats);
|
||||
|
||||
already_probed:
|
||||
beach:
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_release_device_caps_and_formats (GstCelVideoSrc * self)
|
||||
{
|
||||
if (self->device_caps != NULL) {
|
||||
gst_caps_unref (self->device_caps);
|
||||
self->device_caps = NULL;
|
||||
}
|
||||
|
||||
if (self->device_formats != NULL) {
|
||||
g_array_free (self->device_formats, TRUE);
|
||||
self->device_formats = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_select_format (GstCelVideoSrc * self,
|
||||
GstCelVideoFormat * format)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
GstMTApi *mt = self->ctx->mt;
|
||||
GstCelApi *cel = self->ctx->cel;
|
||||
OSStatus status;
|
||||
SInt32 framerate;
|
||||
|
||||
status = gst_cel_video_src_set_stream_property_i32 (self,
|
||||
*(mt->kFigCaptureStreamProperty_FormatIndex), format->index);
|
||||
if (status != noErr)
|
||||
goto beach;
|
||||
|
||||
framerate = format->fps_n / format->fps_d;
|
||||
|
||||
status = gst_cel_video_src_set_stream_property_i32 (self,
|
||||
*(mt->kFigCaptureStreamProperty_MinimumFrameRate), framerate);
|
||||
if (status != noErr)
|
||||
goto beach;
|
||||
|
||||
status = gst_cel_video_src_set_stream_property_i32 (self,
|
||||
*(mt->kFigCaptureStreamProperty_MaximumFrameRate), framerate);
|
||||
if (status != noErr)
|
||||
goto beach;
|
||||
|
||||
status = gst_cel_video_src_set_stream_property_value (self,
|
||||
*(cel->kFigCaptureStreamProperty_ColorRange),
|
||||
*(cel->kFigCapturePropertyValue_ColorRangeSDVideo));
|
||||
if (status != noErr)
|
||||
goto beach;
|
||||
|
||||
status = self->stream_iface->Start (self->stream);
|
||||
if (status != noErr)
|
||||
goto beach;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "configured format %d (%d x %d @ %d Hz)",
|
||||
format->index, format->width, format->height, (gint) framerate);
|
||||
|
||||
self->duration =
|
||||
gst_util_uint64_scale (GST_SECOND, format->fps_d, format->fps_n);
|
||||
|
||||
result = TRUE;
|
||||
|
||||
beach:
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_cel_video_src_parse_stream_format (GstCelVideoSrc * self,
|
||||
guint index, CFDictionaryRef stream_format, GstCelVideoFormat * format)
|
||||
{
|
||||
GstCMApi *cm = self->ctx->cm;
|
||||
GstMTApi *mt = self->ctx->mt;
|
||||
CMFormatDescriptionRef desc;
|
||||
CMVideoDimensions dim;
|
||||
UInt32 subtype;
|
||||
CFNumberRef framerate_value;
|
||||
SInt32 fps_n;
|
||||
|
||||
format->index = index;
|
||||
|
||||
desc = CFDictionaryGetValue (stream_format,
|
||||
*(mt->kFigSupportedFormat_FormatDescription));
|
||||
|
||||
dim = cm->CMVideoFormatDescriptionGetDimensions (desc);
|
||||
format->width = dim.width;
|
||||
format->height = dim.height;
|
||||
|
||||
subtype = cm->CMFormatDescriptionGetMediaSubType (desc);
|
||||
|
||||
switch (subtype) {
|
||||
case kComponentVideoUnsigned:
|
||||
format->video_format = GST_VIDEO_FORMAT_YUY2;
|
||||
format->fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
|
||||
break;
|
||||
case kYUV420vCodecType:
|
||||
format->video_format = GST_VIDEO_FORMAT_NV12;
|
||||
format->fourcc = GST_MAKE_FOURCC ('N', 'V', '1', '2');
|
||||
break;
|
||||
default:
|
||||
goto unsupported_format;
|
||||
}
|
||||
|
||||
framerate_value = CFDictionaryGetValue (stream_format,
|
||||
*(mt->kFigSupportedFormat_VideoMaxFrameRate));
|
||||
CFNumberGetValue (framerate_value, kCFNumberSInt32Type, &fps_n);
|
||||
format->fps_n = fps_n;
|
||||
format->fps_d = 1;
|
||||
|
||||
return TRUE;
|
||||
|
||||
unsupported_format:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static OSStatus
|
||||
gst_cel_video_src_set_stream_property_i32 (GstCelVideoSrc * self,
|
||||
CFStringRef name, SInt32 value)
|
||||
{
|
||||
OSStatus status;
|
||||
CFNumberRef number;
|
||||
|
||||
number = CFNumberCreate (NULL, kCFNumberSInt32Type, &value);
|
||||
status = self->stream_base_iface->SetProperty (self->stream_base, name,
|
||||
number);
|
||||
CFRelease (number);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static OSStatus
|
||||
gst_cel_video_src_set_stream_property_value (GstCelVideoSrc * self,
|
||||
CFStringRef name, CFTypeRef value)
|
||||
{
|
||||
return self->stream_base_iface->SetProperty (self->stream_base, name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_base_init (gpointer gclass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
|
||||
|
||||
gst_element_class_set_metadata (element_class,
|
||||
"Video Source (Celestial)", "Source/Video",
|
||||
"Reads frames from an iOS Celestial device",
|
||||
"Ole André Vadla Ravnås <oleavr@soundrop.com>");
|
||||
|
||||
gst_element_class_add_static_pad_template (element_class, &src_template);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cel_video_src_class_init (GstCelVideoSrcClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
|
||||
GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
|
||||
GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gst_cel_video_src_dispose;
|
||||
gobject_class->finalize = gst_cel_video_src_finalize;
|
||||
gobject_class->get_property = gst_cel_video_src_get_property;
|
||||
gobject_class->set_property = gst_cel_video_src_set_property;
|
||||
|
||||
gstelement_class->change_state = gst_cel_video_src_change_state;
|
||||
|
||||
gstbasesrc_class->get_caps = gst_cel_video_src_get_caps;
|
||||
gstbasesrc_class->set_caps = gst_cel_video_src_set_caps;
|
||||
gstbasesrc_class->start = gst_cel_video_src_start;
|
||||
gstbasesrc_class->stop = gst_cel_video_src_stop;
|
||||
gstbasesrc_class->query = gst_cel_video_src_query;
|
||||
gstbasesrc_class->unlock = gst_cel_video_src_unlock;
|
||||
gstbasesrc_class->unlock_stop = gst_cel_video_src_unlock_stop;
|
||||
|
||||
gstpushsrc_class->create = gst_cel_video_src_create;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_DEVICE_INDEX,
|
||||
g_param_spec_int ("device-index", "Device Index",
|
||||
"The zero-based device index",
|
||||
-1, G_MAXINT, DEFAULT_DEVICE_INDEX,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_DO_STATS,
|
||||
g_param_spec_boolean ("do-stats", "Enable statistics",
|
||||
"Enable logging of statistics", DEFAULT_DO_STATS,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_FPS,
|
||||
g_param_spec_int ("fps", "Frames per second",
|
||||
"Last measured framerate, if statistics are enabled",
|
||||
-1, G_MAXINT, -1, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_cel_video_src_debug, "celvideosrc",
|
||||
0, "iOS Celestial video source");
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_CEL_VIDEO_SRC_H__
|
||||
#define __GST_CEL_VIDEO_SRC_H__
|
||||
|
||||
#include <gst/base/gstpushsrc.h>
|
||||
|
||||
#include "coremediactx.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CEL_VIDEO_SRC \
|
||||
(gst_cel_video_src_get_type ())
|
||||
#define GST_CEL_VIDEO_SRC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CEL_VIDEO_SRC, GstCelVideoSrc))
|
||||
#define GST_CEL_VIDEO_SRC_CAST(obj) \
|
||||
((GstCelVideoSrc *) (obj))
|
||||
#define GST_CEL_VIDEO_SRC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CEL_VIDEO_SRC, GstCelVideoSrcClass))
|
||||
#define GST_IS_CEL_VIDEO_SRC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CEL_VIDEO_SRC))
|
||||
#define GST_IS_CEL_VIDEO_SRC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CEL_VIDEO_SRC))
|
||||
|
||||
typedef struct _GstCelVideoSrc GstCelVideoSrc;
|
||||
typedef struct _GstCelVideoSrcClass GstCelVideoSrcClass;
|
||||
|
||||
struct _GstCelVideoSrc
|
||||
{
|
||||
GstPushSrc push_src;
|
||||
|
||||
gint device_index;
|
||||
gboolean do_stats;
|
||||
|
||||
GstCoreMediaCtx *ctx;
|
||||
|
||||
FigCaptureDeviceRef device;
|
||||
FigCaptureDeviceIface *device_iface;
|
||||
FigBaseObjectRef device_base;
|
||||
FigBaseIface *device_base_iface;
|
||||
FigCaptureStreamRef stream;
|
||||
FigCaptureStreamIface *stream_iface;
|
||||
FigBaseObjectRef stream_base;
|
||||
FigBaseIface *stream_base_iface;
|
||||
|
||||
CMBufferQueueRef queue;
|
||||
CMBufferQueueTriggerToken ready_trigger;
|
||||
GstCaps *device_caps;
|
||||
GArray *device_formats;
|
||||
GstClockTime duration;
|
||||
|
||||
volatile gint is_running;
|
||||
guint64 offset;
|
||||
|
||||
GCond *ready_cond;
|
||||
volatile gboolean queue_is_ready;
|
||||
|
||||
GstClockTime last_sampling;
|
||||
guint count;
|
||||
gint fps;
|
||||
};
|
||||
|
||||
struct _GstCelVideoSrcClass
|
||||
{
|
||||
GstPushSrcClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_cel_video_src_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CEL_VIDEO_SRC_H__ */
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "cmapi.h"
|
||||
|
||||
#include "dynapi-internal.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#define CM_FRAMEWORK_PATH "/System/Library/Frameworks/" \
|
||||
"CoreMedia.framework/CoreMedia"
|
||||
#define CM_FRAMEWORK_PATH_OLD "/System/Library/PrivateFrameworks/" \
|
||||
"CoreMedia.framework/CoreMedia"
|
||||
|
||||
G_DEFINE_TYPE (GstCMApi, gst_cm_api, GST_TYPE_DYN_API);
|
||||
|
||||
static void
|
||||
gst_cm_api_init (GstCMApi * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cm_api_class_init (GstCMApiClass * klass)
|
||||
{
|
||||
}
|
||||
|
||||
#define SYM_SPEC(name) GST_DYN_SYM_SPEC (GstCMApi, name)
|
||||
|
||||
GstCMApi *
|
||||
gst_cm_api_obtain (GError ** error)
|
||||
{
|
||||
static const GstDynSymSpec symbols[] = {
|
||||
SYM_SPEC (FigBaseObjectGetVTable),
|
||||
|
||||
SYM_SPEC (CMGetAttachment),
|
||||
|
||||
SYM_SPEC (FigFormatDescriptionRelease),
|
||||
SYM_SPEC (FigFormatDescriptionRetain),
|
||||
SYM_SPEC (CMFormatDescriptionEqual),
|
||||
SYM_SPEC (CMFormatDescriptionGetExtension),
|
||||
SYM_SPEC (CMFormatDescriptionGetMediaType),
|
||||
SYM_SPEC (CMFormatDescriptionGetMediaSubType),
|
||||
|
||||
SYM_SPEC (CMVideoFormatDescriptionCreate),
|
||||
SYM_SPEC
|
||||
(FigVideoFormatDescriptionCreateWithSampleDescriptionExtensionAtom),
|
||||
SYM_SPEC (CMVideoFormatDescriptionGetDimensions),
|
||||
|
||||
SYM_SPEC (CMTimeMake),
|
||||
|
||||
SYM_SPEC (CMSampleBufferCreate),
|
||||
SYM_SPEC (CMSampleBufferDataIsReady),
|
||||
SYM_SPEC (CMSampleBufferGetDataBuffer),
|
||||
SYM_SPEC (CMSampleBufferGetFormatDescription),
|
||||
SYM_SPEC (CMSampleBufferGetImageBuffer),
|
||||
SYM_SPEC (CMSampleBufferGetNumSamples),
|
||||
SYM_SPEC (CMSampleBufferGetSampleAttachmentsArray),
|
||||
SYM_SPEC (CMSampleBufferGetSampleSize),
|
||||
SYM_SPEC (FigSampleBufferRelease),
|
||||
SYM_SPEC (FigSampleBufferRetain),
|
||||
|
||||
SYM_SPEC (CMBlockBufferCreateWithMemoryBlock),
|
||||
SYM_SPEC (CMBlockBufferGetDataLength),
|
||||
SYM_SPEC (CMBlockBufferGetDataPointer),
|
||||
SYM_SPEC (FigBlockBufferRelease),
|
||||
SYM_SPEC (FigBlockBufferRetain),
|
||||
|
||||
SYM_SPEC (CMBufferQueueDequeueAndRetain),
|
||||
SYM_SPEC (CMBufferQueueGetBufferCount),
|
||||
SYM_SPEC (CMBufferQueueInstallTrigger),
|
||||
SYM_SPEC (CMBufferQueueIsEmpty),
|
||||
SYM_SPEC (FigBufferQueueRelease),
|
||||
SYM_SPEC (CMBufferQueueRemoveTrigger),
|
||||
SYM_SPEC (CMBufferQueueSetValidationCallback),
|
||||
|
||||
SYM_SPEC (kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms),
|
||||
SYM_SPEC (kCMSampleAttachmentKey_DependsOnOthers),
|
||||
SYM_SPEC (kCMTimeInvalid),
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
GstCMApi *result;
|
||||
GModule *module;
|
||||
|
||||
/* We cannot stat() the library as it may not be present on the filesystem.
|
||||
* This is the case on newer versions of iOS where system libraries are all
|
||||
* part of dyld_shared_cache... */
|
||||
module = g_module_open (CM_FRAMEWORK_PATH, 0);
|
||||
if (module != NULL) {
|
||||
result = _gst_dyn_api_new (gst_cm_api_get_type (), CM_FRAMEWORK_PATH,
|
||||
symbols, error);
|
||||
g_module_close (module);
|
||||
} else {
|
||||
GstDynSymSpec *old_symbols;
|
||||
guint i;
|
||||
|
||||
old_symbols = g_memdup (symbols, sizeof (symbols));
|
||||
for (i = 0; old_symbols[i].name != NULL; i++) {
|
||||
const gchar *name = old_symbols[i].name;
|
||||
const gchar *translated_name;
|
||||
|
||||
if (g_str_has_prefix (name, "CM"))
|
||||
translated_name = g_strconcat ("Fig", name + 2, NULL);
|
||||
else if (g_str_has_prefix (name, "kCM"))
|
||||
translated_name = g_strconcat ("kFig", name + 3, NULL);
|
||||
else
|
||||
translated_name = g_strdup (name);
|
||||
|
||||
old_symbols[i].name = translated_name;
|
||||
}
|
||||
|
||||
result = _gst_dyn_api_new (gst_cm_api_get_type (), CM_FRAMEWORK_PATH_OLD,
|
||||
old_symbols, error);
|
||||
|
||||
for (i = 0; old_symbols[i].name != NULL; i++)
|
||||
g_free ((gpointer) old_symbols[i].name);
|
||||
g_free (old_symbols);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,212 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_CM_API_H__
|
||||
#define __GST_CM_API_H__
|
||||
|
||||
#include "dynapi.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "cvapi.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstCMApi GstCMApi;
|
||||
typedef struct _GstCMApiClass GstCMApiClass;
|
||||
|
||||
typedef CFTypeRef FigBaseObjectRef;
|
||||
typedef struct _FigBaseVTable FigBaseVTable;
|
||||
typedef struct _FigBaseIface FigBaseIface;
|
||||
|
||||
typedef CFTypeRef CMFormatDescriptionRef;
|
||||
typedef struct _CMVideoDimensions CMVideoDimensions;
|
||||
typedef struct _CMTime CMTime;
|
||||
|
||||
typedef CFTypeRef CMBufferQueueRef;
|
||||
typedef SInt32 CMBufferQueueTriggerCondition;
|
||||
typedef struct _CMBufferQueueTriggerToken *CMBufferQueueTriggerToken;
|
||||
typedef CFTypeRef CMSampleBufferRef;
|
||||
typedef CFTypeRef CMBlockBufferRef;
|
||||
|
||||
typedef void (* CMBufferQueueTriggerCallback) (void *triggerRefcon,
|
||||
CMBufferQueueTriggerToken triggerToken);
|
||||
typedef Boolean (* CMBufferQueueValidationCallback) (CMBufferQueueRef queue,
|
||||
CMSampleBufferRef buf, void *refCon);
|
||||
|
||||
enum _FigMediaType
|
||||
{
|
||||
kFigMediaTypeVideo = 'vide'
|
||||
};
|
||||
|
||||
enum _FigCodecType
|
||||
{
|
||||
kComponentVideoUnsigned = 'yuvs',
|
||||
kFigVideoCodecType_JPEG_OpenDML = 'dmb1',
|
||||
kYUV420vCodecType = '420v'
|
||||
};
|
||||
|
||||
enum _CMBufferQueueTriggerCondition
|
||||
{
|
||||
kCMBufferQueueTrigger_WhenDurationBecomesLessThan = 1,
|
||||
kCMBufferQueueTrigger_WhenDurationBecomesLessThanOrEqualTo = 2,
|
||||
kCMBufferQueueTrigger_WhenDurationBecomesGreaterThan = 3,
|
||||
kCMBufferQueueTrigger_WhenDurationBecomesGreaterThanOrEqualTo = 4,
|
||||
kCMBufferQueueTrigger_WhenMinPresentationTimeStampChanges = 5,
|
||||
kCMBufferQueueTrigger_WhenMaxPresentationTimeStampChanges = 6,
|
||||
kCMBufferQueueTrigger_WhenDataBecomesReady = 7,
|
||||
kCMBufferQueueTrigger_WhenEndOfDataReached = 8,
|
||||
kCMBufferQueueTrigger_WhenReset = 9,
|
||||
kCMBufferQueueTrigger_WhenBufferCountBecomesLessThan = 10,
|
||||
kCMBufferQueueTrigger_WhenBufferCountBecomesGreaterThan = 11
|
||||
};
|
||||
|
||||
struct _FigBaseVTable
|
||||
{
|
||||
gsize unk;
|
||||
FigBaseIface * base;
|
||||
void * derived;
|
||||
};
|
||||
|
||||
struct _FigBaseIface
|
||||
{
|
||||
gsize unk1;
|
||||
gsize unk2;
|
||||
gsize unk3;
|
||||
OSStatus (* Invalidate) (FigBaseObjectRef obj);
|
||||
OSStatus (* Finalize) (FigBaseObjectRef obj);
|
||||
gpointer unk4;
|
||||
OSStatus (* CopyProperty) (FigBaseObjectRef obj, CFTypeRef key, void *unk,
|
||||
CFTypeRef * value);
|
||||
OSStatus (* SetProperty) (FigBaseObjectRef obj, CFTypeRef key,
|
||||
CFTypeRef value);
|
||||
};
|
||||
|
||||
struct _CMVideoDimensions
|
||||
{
|
||||
UInt32 width;
|
||||
UInt32 height;
|
||||
};
|
||||
|
||||
struct _CMTime
|
||||
{
|
||||
UInt8 data[24];
|
||||
};
|
||||
|
||||
struct _GstCMApi
|
||||
{
|
||||
GstDynApi parent;
|
||||
|
||||
FigBaseVTable * (* FigBaseObjectGetVTable) (FigBaseObjectRef obj);
|
||||
|
||||
void * (* CMGetAttachment) (CFTypeRef obj, CFStringRef attachmentKey,
|
||||
UInt32 * foundWherePtr);
|
||||
|
||||
void (* FigFormatDescriptionRelease) (CMFormatDescriptionRef desc);
|
||||
CMFormatDescriptionRef (* FigFormatDescriptionRetain) (
|
||||
CMFormatDescriptionRef desc);
|
||||
Boolean (* CMFormatDescriptionEqual) (CMFormatDescriptionRef desc1,
|
||||
CMFormatDescriptionRef desc2);
|
||||
CFTypeRef (* CMFormatDescriptionGetExtension) (
|
||||
const CMFormatDescriptionRef desc, CFStringRef extensionKey);
|
||||
UInt32 (* CMFormatDescriptionGetMediaType) (
|
||||
const CMFormatDescriptionRef desc);
|
||||
UInt32 (* CMFormatDescriptionGetMediaSubType) (
|
||||
const CMFormatDescriptionRef desc);
|
||||
|
||||
OSStatus (* CMVideoFormatDescriptionCreate) (
|
||||
CFAllocatorRef allocator, UInt32 formatId, UInt32 width, UInt32 height,
|
||||
CFDictionaryRef extensions, CMFormatDescriptionRef * desc);
|
||||
OSStatus (* FigVideoFormatDescriptionCreateWithSampleDescriptionExtensionAtom)
|
||||
(CFAllocatorRef allocator, UInt32 formatId, UInt32 width, UInt32 height,
|
||||
UInt32 atomId, const UInt8 * data, CFIndex len, void *unk1,
|
||||
CMFormatDescriptionRef * formatDesc);
|
||||
CMVideoDimensions (* CMVideoFormatDescriptionGetDimensions) (
|
||||
const CMFormatDescriptionRef desc);
|
||||
|
||||
CMTime (* CMTimeMake) (int64_t value, int32_t timescale);
|
||||
|
||||
OSStatus (* CMSampleBufferCreate) (CFAllocatorRef allocator,
|
||||
CMBlockBufferRef blockBuf, Boolean dataReady,
|
||||
void *makeDataReadyCallback,
|
||||
void *makeDataReadyRefcon,
|
||||
CMFormatDescriptionRef fmtDesc, size_t numSamples,
|
||||
size_t numSampleTimingEntries,
|
||||
const void *sampleTimingArray,
|
||||
size_t numSampleSizeEntries, const size_t *sampleSizeArray,
|
||||
CMSampleBufferRef * sampleBuffer);
|
||||
Boolean (* CMSampleBufferDataIsReady) (
|
||||
const CMSampleBufferRef buf);
|
||||
CMBlockBufferRef (* CMSampleBufferGetDataBuffer) (
|
||||
const CMSampleBufferRef buf);
|
||||
CMFormatDescriptionRef (* CMSampleBufferGetFormatDescription) (
|
||||
const CMSampleBufferRef buf);
|
||||
CVImageBufferRef (* CMSampleBufferGetImageBuffer) (
|
||||
const CMSampleBufferRef buf);
|
||||
SInt32 (* CMSampleBufferGetNumSamples) (
|
||||
const CMSampleBufferRef buf);
|
||||
CFArrayRef (* CMSampleBufferGetSampleAttachmentsArray) (
|
||||
const CMSampleBufferRef buf, SInt32 sampleIndex);
|
||||
SInt32 (* CMSampleBufferGetSampleSize) (
|
||||
const CMSampleBufferRef buf, SInt32 sampleIndex);
|
||||
void (* FigSampleBufferRelease) (CMSampleBufferRef buf);
|
||||
CMSampleBufferRef (* FigSampleBufferRetain) (CMSampleBufferRef buf);
|
||||
|
||||
OSStatus (* CMBlockBufferCreateWithMemoryBlock)
|
||||
(CFAllocatorRef allocator, void * memoryBlock, size_t blockLength,
|
||||
CFAllocatorRef dataAllocator, void *customBlockSource,
|
||||
size_t offsetToData, size_t dataLength,
|
||||
int flags, CMBlockBufferRef * blockBuffer);
|
||||
SInt32 (* CMBlockBufferGetDataLength) (const CMBlockBufferRef buf);
|
||||
OSStatus (* CMBlockBufferGetDataPointer) (
|
||||
const CMBlockBufferRef buf, UInt32 unk1, UInt32 unk2, UInt32 unk3,
|
||||
Byte ** dataPtr);
|
||||
void (* FigBlockBufferRelease) (CMBlockBufferRef buf);
|
||||
CMBlockBufferRef (* FigBlockBufferRetain) (CMBlockBufferRef buf);
|
||||
|
||||
CMSampleBufferRef (* CMBufferQueueDequeueAndRetain)
|
||||
(CMBufferQueueRef queue);
|
||||
CFIndex (* CMBufferQueueGetBufferCount) (CMBufferQueueRef queue);
|
||||
OSStatus (* CMBufferQueueInstallTrigger) (CMBufferQueueRef queue,
|
||||
CMBufferQueueTriggerCallback triggerCallback, void * triggerRefCon,
|
||||
CMBufferQueueTriggerCondition triggerCondition, CMTime triggerTime,
|
||||
CMBufferQueueTriggerToken * triggerTokenOut);
|
||||
Boolean (* CMBufferQueueIsEmpty) (CMBufferQueueRef queue);
|
||||
void (* FigBufferQueueRelease) (CMBufferQueueRef queue);
|
||||
OSStatus (* CMBufferQueueRemoveTrigger) (CMBufferQueueRef queue,
|
||||
CMBufferQueueTriggerToken triggerToken);
|
||||
OSStatus (* CMBufferQueueSetValidationCallback) (CMBufferQueueRef queue,
|
||||
CMBufferQueueValidationCallback func, void *refCon);
|
||||
|
||||
CFStringRef * kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms;
|
||||
CFStringRef * kCMSampleAttachmentKey_DependsOnOthers;
|
||||
CMTime * kCMTimeInvalid;
|
||||
};
|
||||
|
||||
struct _GstCMApiClass
|
||||
{
|
||||
GstDynApiClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_cm_api_get_type (void);
|
||||
|
||||
GstCMApi * gst_cm_api_obtain (GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "coremediabuffer.h"
|
||||
|
||||
static gboolean
|
||||
gst_core_media_meta_init (GstCoreMediaMeta * meta, gpointer params,
|
||||
GstBuffer * buf)
|
||||
{
|
||||
meta->ctx = NULL;
|
||||
meta->sample_buf = NULL;
|
||||
meta->image_buf = NULL;
|
||||
meta->pixel_buf = NULL;
|
||||
meta->block_buf = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf)
|
||||
{
|
||||
if (meta->image_buf != NULL) {
|
||||
GstCVApi *cv = meta->ctx->cv;
|
||||
cv->CVPixelBufferUnlockBaseAddress (meta->image_buf,
|
||||
kCVPixelBufferLock_ReadOnly);
|
||||
}
|
||||
meta->ctx->cm->FigSampleBufferRelease (meta->sample_buf);
|
||||
g_object_unref (meta->ctx);
|
||||
}
|
||||
|
||||
GType
|
||||
gst_core_media_meta_api_get_type (void)
|
||||
{
|
||||
static volatile GType type;
|
||||
static const gchar *tags[] = { "memory", NULL };
|
||||
|
||||
if (g_once_init_enter (&type)) {
|
||||
GType _type = gst_meta_api_type_register ("GstCoreMediaMetaAPI", tags);
|
||||
g_once_init_leave (&type, _type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static const GstMetaInfo *
|
||||
gst_core_media_meta_get_info (void)
|
||||
{
|
||||
static const GstMetaInfo *core_media_meta_info = NULL;
|
||||
|
||||
if (g_once_init_enter (&core_media_meta_info)) {
|
||||
const GstMetaInfo *meta = gst_meta_register (GST_CORE_MEDIA_META_API_TYPE,
|
||||
"GstCoreMediaMeta", sizeof (GstCoreMediaMeta),
|
||||
(GstMetaInitFunction) gst_core_media_meta_init,
|
||||
(GstMetaFreeFunction) gst_core_media_meta_free,
|
||||
(GstMetaTransformFunction) NULL);
|
||||
g_once_init_leave (&core_media_meta_info, meta);
|
||||
}
|
||||
return core_media_meta_info;
|
||||
}
|
||||
|
||||
GstBuffer *
|
||||
gst_core_media_buffer_new (GstCoreMediaCtx * ctx, CMSampleBufferRef sample_buf)
|
||||
{
|
||||
GstCVApi *cv = ctx->cv;
|
||||
GstCMApi *cm = ctx->cm;
|
||||
CVImageBufferRef image_buf;
|
||||
CVPixelBufferRef pixel_buf;
|
||||
CMBlockBufferRef block_buf;
|
||||
Byte *data = NULL;
|
||||
UInt32 size;
|
||||
OSStatus status;
|
||||
GstBuffer *buf;
|
||||
GstCoreMediaMeta *meta;
|
||||
|
||||
image_buf = cm->CMSampleBufferGetImageBuffer (sample_buf);
|
||||
pixel_buf = NULL;
|
||||
block_buf = cm->CMSampleBufferGetDataBuffer (sample_buf);
|
||||
|
||||
if (image_buf != NULL &&
|
||||
CFGetTypeID (image_buf) == cv->CVPixelBufferGetTypeID ()) {
|
||||
pixel_buf = (CVPixelBufferRef) image_buf;
|
||||
|
||||
if (cv->CVPixelBufferLockBaseAddress (pixel_buf,
|
||||
kCVPixelBufferLock_ReadOnly) != kCVReturnSuccess) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cv->CVPixelBufferIsPlanar (pixel_buf)) {
|
||||
gint plane_count, plane_idx;
|
||||
|
||||
data = cv->CVPixelBufferGetBaseAddressOfPlane (pixel_buf, 0);
|
||||
|
||||
size = 0;
|
||||
plane_count = cv->CVPixelBufferGetPlaneCount (pixel_buf);
|
||||
for (plane_idx = 0; plane_idx != plane_count; plane_idx++) {
|
||||
size += cv->CVPixelBufferGetBytesPerRowOfPlane (pixel_buf, plane_idx) *
|
||||
cv->CVPixelBufferGetHeightOfPlane (pixel_buf, plane_idx);
|
||||
}
|
||||
} else {
|
||||
data = cv->CVPixelBufferGetBaseAddress (pixel_buf);
|
||||
size = cv->CVPixelBufferGetBytesPerRow (pixel_buf) *
|
||||
cv->CVPixelBufferGetHeight (pixel_buf);
|
||||
}
|
||||
} else if (block_buf != NULL) {
|
||||
status = cm->CMBlockBufferGetDataPointer (block_buf, 0, 0, 0, &data);
|
||||
if (status != noErr)
|
||||
goto error;
|
||||
size = cm->CMBlockBufferGetDataLength (block_buf);
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
|
||||
meta = (GstCoreMediaMeta *) gst_buffer_add_meta (buf,
|
||||
gst_core_media_meta_get_info (), NULL);
|
||||
meta->ctx = g_object_ref (ctx);
|
||||
meta->sample_buf = cm->FigSampleBufferRetain (sample_buf);
|
||||
meta->image_buf = image_buf;
|
||||
meta->pixel_buf = pixel_buf;
|
||||
meta->block_buf = block_buf;
|
||||
|
||||
gst_buffer_append_memory (buf,
|
||||
gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, data,
|
||||
size, 0, size, NULL, NULL));
|
||||
|
||||
return buf;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CVPixelBufferRef
|
||||
gst_core_media_buffer_get_pixel_buffer (GstBuffer * buf)
|
||||
{
|
||||
GstCoreMediaMeta *meta = (GstCoreMediaMeta *) gst_buffer_get_meta (buf,
|
||||
GST_CORE_MEDIA_META_API_TYPE);
|
||||
g_return_val_if_fail (meta != NULL, NULL);
|
||||
|
||||
return meta->ctx->cv->CVPixelBufferRetain (meta->pixel_buf);
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_CORE_MEDIA_BUFFER_H__
|
||||
#define __GST_CORE_MEDIA_BUFFER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "coremediactx.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_CORE_MEDIA_META_API_TYPE (gst_core_media_meta_api_get_type())
|
||||
#define gst_buffer_get_core_media_meta(b) \
|
||||
((GstCoreMediaMeta*)gst_buffer_get_meta((b),GST_CORE_MEDIA_META_API_TYPE))
|
||||
|
||||
typedef struct _GstCoreMediaMeta
|
||||
{
|
||||
GstMeta meta;
|
||||
|
||||
GstCoreMediaCtx * ctx;
|
||||
CMSampleBufferRef sample_buf;
|
||||
CVImageBufferRef image_buf;
|
||||
CVPixelBufferRef pixel_buf;
|
||||
CMBlockBufferRef block_buf;
|
||||
} GstCoreMediaMeta;
|
||||
|
||||
|
||||
GstBuffer * gst_core_media_buffer_new (GstCoreMediaCtx * ctx,
|
||||
CMSampleBufferRef sample_buf);
|
||||
CVPixelBufferRef gst_core_media_buffer_get_pixel_buffer
|
||||
(GstBuffer * buf);
|
||||
GType gst_core_media_meta_api_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CORE_MEDIA_BUFFER_H__ */
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "coremediactx.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
typedef struct _GstApiProvider GstApiProvider;
|
||||
|
||||
typedef gpointer (*GstApiProviderObtainFunc) (GError ** error);
|
||||
|
||||
struct _GstApiProvider
|
||||
{
|
||||
GstCoreMediaApi api;
|
||||
GstApiProviderObtainFunc obtain;
|
||||
guint offset;
|
||||
};
|
||||
|
||||
#define API_PROVIDER(AN, a_n) \
|
||||
{ GST_API_##AN, (GstApiProviderObtainFunc) gst_##a_n##_api_obtain, \
|
||||
G_STRUCT_OFFSET (GstCoreMediaCtx, a_n) }
|
||||
|
||||
static const GstApiProvider api_provider[] = {
|
||||
API_PROVIDER (CORE_VIDEO, cv),
|
||||
API_PROVIDER (CORE_MEDIA, cm),
|
||||
#ifdef HAVE_IOS
|
||||
#if 0
|
||||
API_PROVIDER (MEDIA_TOOLBOX, mt),
|
||||
API_PROVIDER (CELESTIAL, cel)
|
||||
#endif
|
||||
#else
|
||||
API_PROVIDER (MIO, mio),
|
||||
#endif
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstCoreMediaCtx, gst_core_media_ctx, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gst_core_media_ctx_init (GstCoreMediaCtx * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_core_media_ctx_dispose (GObject * object)
|
||||
{
|
||||
GstCoreMediaCtx *self = GST_CORE_MEDIA_CTX_CAST (object);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i != G_N_ELEMENTS (api_provider); i++) {
|
||||
const GstApiProvider *ap = &api_provider[i];
|
||||
gpointer *api_ptr = (gpointer *) ((guint8 *) self + ap->offset);
|
||||
|
||||
if (*api_ptr != NULL) {
|
||||
g_object_unref (*api_ptr);
|
||||
*api_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gst_core_media_ctx_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_core_media_ctx_class_init (GstCoreMediaCtxClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gst_core_media_ctx_dispose;
|
||||
}
|
||||
|
||||
GstCoreMediaCtx *
|
||||
gst_core_media_ctx_new (GstCoreMediaApi required_apis, GError ** error)
|
||||
{
|
||||
GstCoreMediaCtx *ctx;
|
||||
GArray *error_messages;
|
||||
guint i;
|
||||
|
||||
ctx = g_object_new (GST_TYPE_CORE_MEDIA_CTX, NULL);
|
||||
|
||||
error_messages = g_array_new (TRUE, FALSE, sizeof (gchar *));
|
||||
|
||||
for (i = 0; i != G_N_ELEMENTS (api_provider); i++) {
|
||||
const GstApiProvider *ap = &api_provider[i];
|
||||
|
||||
if ((required_apis & ap->api) != 0) {
|
||||
gpointer *api_ptr = (gpointer *) ((guint8 *) ctx + ap->offset);
|
||||
GError *tmp_error = NULL;
|
||||
|
||||
*api_ptr = ap->obtain (&tmp_error);
|
||||
if (tmp_error != NULL) {
|
||||
gchar *message_copy = g_strdup (tmp_error->message);
|
||||
g_array_append_val (error_messages, message_copy);
|
||||
g_clear_error (&tmp_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error_messages->len != 0) {
|
||||
gchar *errors_joined;
|
||||
|
||||
errors_joined = g_strjoinv ("\n\t* ", (gchar **) error_messages->data);
|
||||
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
|
||||
"Could not obtain required API%s:%s%s",
|
||||
(error_messages->len == 1) ? "" : "s",
|
||||
(error_messages->len == 1) ? " " : "\n\t* ", errors_joined);
|
||||
g_free (errors_joined);
|
||||
|
||||
g_object_unref (ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i != error_messages->len; i++)
|
||||
g_free (g_array_index (error_messages, gchar *, i));
|
||||
g_array_free (error_messages, TRUE);
|
||||
|
||||
return ctx;
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_CORE_MEDIA_CTX_H__
|
||||
#define __GST_CORE_MEDIA_CTX_H__
|
||||
|
||||
#include "cvapi.h"
|
||||
#include "cmapi.h"
|
||||
|
||||
#include "mioapi.h"
|
||||
|
||||
#include "mtapi.h"
|
||||
#include "celapi.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CORE_MEDIA_CTX \
|
||||
(gst_core_media_ctx_get_type ())
|
||||
#define GST_CORE_MEDIA_CTX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CORE_MEDIA_CTX, GstCoreMediaCtx))
|
||||
#define GST_CORE_MEDIA_CTX_CAST(obj) \
|
||||
((GstCoreMediaCtx *) (obj))
|
||||
#define GST_CORE_MEDIA_CTX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CORE_MEDIA_CTX, GstCoreMediaCtxClass))
|
||||
#define GST_IS_CORE_MEDIA_CTX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CORE_MEDIA_CTX))
|
||||
#define GST_IS_CORE_MEDIA_CTX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CORE_MEDIA_CTX))
|
||||
|
||||
typedef struct _GstCoreMediaCtx GstCoreMediaCtx;
|
||||
typedef struct _GstCoreMediaCtxClass GstCoreMediaCtxClass;
|
||||
|
||||
typedef enum _GstCoreMediaApi GstCoreMediaApi;
|
||||
|
||||
struct _GstCoreMediaCtx
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/* Common */
|
||||
GstCVApi *cv;
|
||||
GstCMApi *cm;
|
||||
|
||||
/* OS X */
|
||||
GstMIOApi *mio;
|
||||
|
||||
/* iPhone */
|
||||
GstMTApi *mt;
|
||||
GstCelApi *cel;
|
||||
};
|
||||
|
||||
struct _GstCoreMediaCtxClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum _GstCoreMediaApi
|
||||
{
|
||||
GST_API_CORE_VIDEO = (1 << 0),
|
||||
GST_API_CORE_MEDIA = (1 << 1),
|
||||
GST_API_VIDEO_TOOLBOX = (1 << 2),
|
||||
|
||||
GST_API_MIO = (1 << 3),
|
||||
|
||||
GST_API_MEDIA_TOOLBOX = (1 << 4),
|
||||
GST_API_CELESTIAL = (1 << 5)
|
||||
};
|
||||
|
||||
GType gst_core_media_ctx_get_type (void);
|
||||
|
||||
GstCoreMediaCtx * gst_core_media_ctx_new (GstCoreMediaApi required_apis,
|
||||
GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "corevideobuffer.h"
|
||||
|
||||
static gboolean
|
||||
gst_core_video_meta_init (GstCoreVideoMeta * meta, gpointer params,
|
||||
GstBuffer * buf)
|
||||
{
|
||||
meta->ctx = NULL;
|
||||
meta->cvbuf = NULL;
|
||||
meta->pixbuf = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_core_video_meta_free (GstCoreVideoMeta * meta, GstBuffer * buf)
|
||||
{
|
||||
GstCVApi *cv = meta->ctx->cv;
|
||||
|
||||
if (meta->pixbuf != NULL) {
|
||||
cv->CVPixelBufferUnlockBaseAddress (meta->pixbuf,
|
||||
kCVPixelBufferLock_ReadOnly);
|
||||
}
|
||||
|
||||
cv->CVBufferRelease (meta->cvbuf);
|
||||
g_object_unref (meta->ctx);
|
||||
}
|
||||
|
||||
GType
|
||||
gst_core_video_meta_api_get_type (void)
|
||||
{
|
||||
static volatile GType type;
|
||||
static const gchar *tags[] = { "memory", NULL };
|
||||
|
||||
if (g_once_init_enter (&type)) {
|
||||
GType _type = gst_meta_api_type_register ("GstCoreVideoMetaAPI", tags);
|
||||
g_once_init_leave (&type, _type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static const GstMetaInfo *
|
||||
gst_core_video_meta_get_info (void)
|
||||
{
|
||||
static const GstMetaInfo *core_video_meta_info = NULL;
|
||||
|
||||
if (g_once_init_enter (&core_video_meta_info)) {
|
||||
const GstMetaInfo *meta = gst_meta_register (GST_CORE_VIDEO_META_API_TYPE,
|
||||
"GstCoreVideoMeta", sizeof (GstCoreVideoMeta),
|
||||
(GstMetaInitFunction) gst_core_video_meta_init,
|
||||
(GstMetaFreeFunction) gst_core_video_meta_free,
|
||||
(GstMetaTransformFunction) NULL);
|
||||
g_once_init_leave (&core_video_meta_info, meta);
|
||||
}
|
||||
return core_video_meta_info;
|
||||
}
|
||||
|
||||
GstBuffer *
|
||||
gst_core_video_buffer_new (GstCoreMediaCtx * ctx, CVBufferRef cvbuf,
|
||||
GstVideoInfo * vinfo)
|
||||
{
|
||||
GstCVApi *cv = ctx->cv;
|
||||
void *data;
|
||||
size_t size;
|
||||
CVPixelBufferRef pixbuf = NULL;
|
||||
GstBuffer *buf;
|
||||
GstCoreVideoMeta *meta;
|
||||
guint width, height, n_planes, i;
|
||||
gsize offset[GST_VIDEO_MAX_PLANES];
|
||||
gint stride[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
if (CFGetTypeID (cvbuf) != cv->CVPixelBufferGetTypeID ())
|
||||
/* TODO: Do we need to handle other buffer types? */
|
||||
goto error;
|
||||
|
||||
pixbuf = (CVPixelBufferRef) cvbuf;
|
||||
|
||||
if (cv->CVPixelBufferLockBaseAddress (pixbuf,
|
||||
kCVPixelBufferLock_ReadOnly) != kCVReturnSuccess) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
|
||||
/* add the corevideo meta to free the underlying corevideo buffer */
|
||||
meta = (GstCoreVideoMeta *) gst_buffer_add_meta (buf,
|
||||
gst_core_video_meta_get_info (), NULL);
|
||||
meta->ctx = g_object_ref (ctx);
|
||||
meta->cvbuf = cv->CVBufferRetain (cvbuf);
|
||||
meta->pixbuf = pixbuf;
|
||||
|
||||
/* set stride, offset and size */
|
||||
memset (&offset, 0, sizeof (offset));
|
||||
memset (&stride, 0, sizeof (stride));
|
||||
|
||||
data = cv->CVPixelBufferGetBaseAddress (pixbuf);
|
||||
height = cv->CVPixelBufferGetHeight (pixbuf);
|
||||
if (cv->CVPixelBufferIsPlanar (pixbuf)) {
|
||||
GstVideoInfo tmp_vinfo;
|
||||
|
||||
n_planes = cv->CVPixelBufferGetPlaneCount (pixbuf);
|
||||
for (i = 0; i < n_planes; ++i)
|
||||
stride[i] = cv->CVPixelBufferGetBytesPerRowOfPlane (pixbuf, i);
|
||||
|
||||
/* FIXME: don't hardcode NV12 */
|
||||
gst_video_info_init (&tmp_vinfo);
|
||||
gst_video_info_set_format (&tmp_vinfo,
|
||||
GST_VIDEO_FORMAT_NV12, stride[0], height);
|
||||
offset[1] = tmp_vinfo.offset[1];
|
||||
size = tmp_vinfo.size;
|
||||
} else {
|
||||
n_planes = 1;
|
||||
size = cv->CVPixelBufferGetBytesPerRow (pixbuf) * height;
|
||||
}
|
||||
|
||||
gst_buffer_append_memory (buf,
|
||||
gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, data,
|
||||
size, 0, size, NULL, NULL));
|
||||
|
||||
if (vinfo) {
|
||||
GstVideoMeta *video_meta;
|
||||
|
||||
width = vinfo->width;
|
||||
video_meta =
|
||||
gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
|
||||
GST_VIDEO_FORMAT_NV12, width, height, n_planes, offset, stride);
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_CORE_VIDEO_BUFFER_H__
|
||||
#define __GST_CORE_VIDEO_BUFFER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/video/gstvideometa.h>
|
||||
|
||||
#include "coremediactx.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_CORE_VIDEO_META_API_TYPE (gst_core_video_meta_api_get_type())
|
||||
#define gst_buffer_get_core_video_meta(b) \
|
||||
((GstCoreVideoMeta*)gst_buffer_get_meta((b),GST_CORE_VIDEO_META_API_TYPE))
|
||||
|
||||
typedef struct _GstCoreVideoMeta
|
||||
{
|
||||
GstMeta meta;
|
||||
|
||||
GstCoreMediaCtx *ctx;
|
||||
CVBufferRef cvbuf;
|
||||
CVPixelBufferRef pixbuf;
|
||||
} GstCoreVideoMeta;
|
||||
|
||||
GstBuffer * gst_core_video_buffer_new (GstCoreMediaCtx * ctx,
|
||||
CVBufferRef cvbuf,
|
||||
GstVideoInfo *info);
|
||||
GType gst_core_video_meta_api_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CORE_VIDEO_BUFFER_H__ */
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "cvapi.h"
|
||||
|
||||
#include "dynapi-internal.h"
|
||||
|
||||
#define CV_FRAMEWORK_PATH "/System/Library/Frameworks/CoreVideo.framework/" \
|
||||
"CoreVideo"
|
||||
|
||||
G_DEFINE_TYPE (GstCVApi, gst_cv_api, GST_TYPE_DYN_API);
|
||||
|
||||
static void
|
||||
gst_cv_api_init (GstCVApi * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_cv_api_class_init (GstCVApiClass * klass)
|
||||
{
|
||||
}
|
||||
|
||||
#define SYM_SPEC(name) GST_DYN_SYM_SPEC (GstCVApi, name)
|
||||
#define SYM_SPEC_OPTIONAL(name) GST_DYN_SYM_SPEC_OPTIONAL (GstCVApi, name)
|
||||
|
||||
GstCVApi *
|
||||
gst_cv_api_obtain (GError ** error)
|
||||
{
|
||||
static const GstDynSymSpec symbols[] = {
|
||||
SYM_SPEC (CVBufferRelease),
|
||||
SYM_SPEC (CVBufferRetain),
|
||||
|
||||
SYM_SPEC (CVPixelBufferCreateWithBytes),
|
||||
SYM_SPEC (CVPixelBufferCreateWithPlanarBytes),
|
||||
SYM_SPEC (CVPixelBufferGetBaseAddress),
|
||||
SYM_SPEC (CVPixelBufferGetBaseAddressOfPlane),
|
||||
SYM_SPEC (CVPixelBufferGetBytesPerRow),
|
||||
SYM_SPEC (CVPixelBufferGetBytesPerRowOfPlane),
|
||||
SYM_SPEC (CVPixelBufferGetHeight),
|
||||
SYM_SPEC (CVPixelBufferGetHeightOfPlane),
|
||||
SYM_SPEC_OPTIONAL (CVPixelBufferGetIOSurface),
|
||||
SYM_SPEC (CVPixelBufferGetPlaneCount),
|
||||
SYM_SPEC (CVPixelBufferGetTypeID),
|
||||
SYM_SPEC (CVPixelBufferIsPlanar),
|
||||
SYM_SPEC (CVPixelBufferLockBaseAddress),
|
||||
SYM_SPEC (CVPixelBufferRelease),
|
||||
SYM_SPEC (CVPixelBufferRetain),
|
||||
SYM_SPEC (CVPixelBufferUnlockBaseAddress),
|
||||
|
||||
SYM_SPEC (kCVPixelBufferPixelFormatTypeKey),
|
||||
SYM_SPEC (kCVPixelBufferWidthKey),
|
||||
SYM_SPEC (kCVPixelBufferHeightKey),
|
||||
SYM_SPEC (kCVPixelBufferBytesPerRowAlignmentKey),
|
||||
SYM_SPEC (kCVPixelBufferPlaneAlignmentKey),
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
return _gst_dyn_api_new (gst_cv_api_get_type (), CV_FRAMEWORK_PATH, symbols,
|
||||
error);
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_CV_API_H__
|
||||
#define __GST_CV_API_H__
|
||||
|
||||
#include "dynapi.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstCVApi GstCVApi;
|
||||
typedef struct _GstCVApiClass GstCVApiClass;
|
||||
|
||||
typedef int32_t CVReturn;
|
||||
|
||||
typedef uint64_t CVOptionFlags;
|
||||
|
||||
typedef struct _CVBuffer * CVBufferRef;
|
||||
typedef CVBufferRef CVImageBufferRef;
|
||||
typedef CVImageBufferRef CVPixelBufferRef;
|
||||
|
||||
typedef void (* CVPixelBufferReleaseBytesCallback) (void * releaseRefCon,
|
||||
const void * baseAddress);
|
||||
|
||||
enum _CVReturn
|
||||
{
|
||||
kCVReturnSuccess = 0
|
||||
};
|
||||
|
||||
enum _CVPixelFormatType
|
||||
{
|
||||
kCVPixelFormatType_420YpCbCr8Planar = 'y420',
|
||||
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v',
|
||||
kCVPixelFormatType_422YpCbCr8Deprecated = 'yuvs',
|
||||
kCVPixelFormatType_422YpCbCr8 = '2vuy'
|
||||
};
|
||||
|
||||
enum _CVPixelBufferLockFlags
|
||||
{
|
||||
kCVPixelBufferLock_ReadOnly = 0x00000001
|
||||
};
|
||||
|
||||
struct _GstCVApi
|
||||
{
|
||||
GstDynApi parent;
|
||||
|
||||
void (* CVBufferRelease) (CVBufferRef buffer);
|
||||
CVBufferRef (* CVBufferRetain) (CVBufferRef buffer);
|
||||
|
||||
CVReturn (* CVPixelBufferCreateWithBytes)
|
||||
(CFAllocatorRef allocator, size_t width, size_t height,
|
||||
OSType pixelFormatType, void * baseAddress, size_t bytesPerRow,
|
||||
CVPixelBufferReleaseBytesCallback releaseCallback,
|
||||
void * releaseRefCon, CFDictionaryRef pixelBufferAttributes,
|
||||
CVPixelBufferRef * pixelBufferOut);
|
||||
CVReturn (* CVPixelBufferCreateWithPlanarBytes)
|
||||
(CFAllocatorRef allocator, size_t width, size_t height,
|
||||
OSType pixelFormatType, void * dataPtr, size_t dataSize,
|
||||
size_t numberOfPlanes, void *planeBaseAddress[],
|
||||
size_t planeWidth[], size_t planeHeight[],
|
||||
size_t planeBytesPerRow[],
|
||||
CVPixelBufferReleaseBytesCallback releaseCallback,
|
||||
void * releaseRefCon, CFDictionaryRef pixelBufferAttributes,
|
||||
CVPixelBufferRef * pixelBufferOut);
|
||||
void * (* CVPixelBufferGetBaseAddress)
|
||||
(CVPixelBufferRef pixelBuffer);
|
||||
void * (* CVPixelBufferGetBaseAddressOfPlane)
|
||||
(CVPixelBufferRef pixelBuffer, size_t planeIndex);
|
||||
size_t (* CVPixelBufferGetBytesPerRow)
|
||||
(CVPixelBufferRef pixelBuffer);
|
||||
size_t (* CVPixelBufferGetBytesPerRowOfPlane)
|
||||
(CVPixelBufferRef pixelBuffer, size_t planeIndex);
|
||||
size_t (* CVPixelBufferGetHeight) (CVPixelBufferRef pixelBuffer);
|
||||
size_t (* CVPixelBufferGetHeightOfPlane)
|
||||
(CVPixelBufferRef pixelBuffer, size_t planeIndex);
|
||||
void * (* CVPixelBufferGetIOSurface)
|
||||
(CVPixelBufferRef pixelBuffer);
|
||||
size_t (* CVPixelBufferGetPlaneCount)
|
||||
(CVPixelBufferRef pixelBuffer);
|
||||
CFTypeID (* CVPixelBufferGetTypeID) (void);
|
||||
Boolean (* CVPixelBufferIsPlanar) (CVPixelBufferRef pixelBuffer);
|
||||
CVReturn (* CVPixelBufferLockBaseAddress)
|
||||
(CVPixelBufferRef pixelBuffer, CVOptionFlags lockFlags);
|
||||
void (* CVPixelBufferRelease) (CVPixelBufferRef pixelBuffer);
|
||||
CVPixelBufferRef (* CVPixelBufferRetain)
|
||||
(CVPixelBufferRef pixelBuffer);
|
||||
CVReturn (* CVPixelBufferUnlockBaseAddress)
|
||||
(CVPixelBufferRef pixelBuffer, CVOptionFlags unlockFlags);
|
||||
|
||||
CFStringRef * kCVPixelBufferPixelFormatTypeKey;
|
||||
CFStringRef * kCVPixelBufferWidthKey;
|
||||
CFStringRef * kCVPixelBufferHeightKey;
|
||||
CFStringRef * kCVPixelBufferBytesPerRowAlignmentKey;
|
||||
CFStringRef * kCVPixelBufferPlaneAlignmentKey;
|
||||
};
|
||||
|
||||
struct _GstCVApiClass
|
||||
{
|
||||
GstDynApiClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_cv_api_get_type (void);
|
||||
|
||||
GstCVApi * gst_cv_api_obtain (GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_DYN_API_INTERNAL_H__
|
||||
#define __GST_DYN_API_INTERNAL_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstDynSymSpec GstDynSymSpec;
|
||||
|
||||
struct _GstDynSymSpec
|
||||
{
|
||||
const gchar * name;
|
||||
guint offset;
|
||||
gboolean is_required;
|
||||
};
|
||||
|
||||
gpointer _gst_dyn_api_new (GType derived_type, const gchar * filename,
|
||||
const GstDynSymSpec * symbols, GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "dynapi.h"
|
||||
|
||||
#include "dynapi-internal.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
GST_DEBUG_CATEGORY (gst_dyn_api_debug);
|
||||
#define GST_CAT_DEFAULT gst_dyn_api_debug
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_FILENAME
|
||||
};
|
||||
|
||||
struct _GstDynApiPrivate
|
||||
{
|
||||
gchar *filename;
|
||||
GModule *module;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstDynApi, gst_dyn_api, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gst_dyn_api_init (GstDynApi * self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_DYN_API,
|
||||
GstDynApiPrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dyn_api_dispose (GObject * object)
|
||||
{
|
||||
GstDynApi *self = GST_DYN_API_CAST (object);
|
||||
GstDynApiPrivate *priv = self->priv;
|
||||
|
||||
if (priv->module != NULL) {
|
||||
g_module_close (priv->module);
|
||||
priv->module = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gst_dyn_api_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dyn_api_finalize (GObject * object)
|
||||
{
|
||||
GstDynApi *self = GST_DYN_API_CAST (object);
|
||||
GstDynApiPrivate *priv = self->priv;
|
||||
|
||||
g_free (priv->filename);
|
||||
|
||||
G_OBJECT_CLASS (gst_dyn_api_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dyn_api_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstDynApi *self = GST_DYN_API (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FILENAME:
|
||||
g_value_set_string (value, self->priv->filename);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dyn_api_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstDynApi *self = GST_DYN_API (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FILENAME:
|
||||
g_free (self->priv->filename);
|
||||
self->priv->filename = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_dyn_api_class_init (GstDynApiClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gst_dyn_api_dispose;
|
||||
gobject_class->finalize = gst_dyn_api_finalize;
|
||||
gobject_class->get_property = gst_dyn_api_get_property;
|
||||
gobject_class->set_property = gst_dyn_api_set_property;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstDynApiPrivate));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_FILENAME,
|
||||
g_param_spec_string ("filename", "Filename", "Filename", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
gpointer
|
||||
_gst_dyn_api_new (GType derived_type, const gchar * filename,
|
||||
const GstDynSymSpec * symbols, GError ** error)
|
||||
{
|
||||
GstDynApi *api;
|
||||
GstDynApiPrivate *priv;
|
||||
guint i;
|
||||
GArray *names_not_found;
|
||||
|
||||
api = g_object_new (derived_type, "filename", filename, NULL);
|
||||
priv = api->priv;
|
||||
|
||||
priv->module = g_module_open (priv->filename, 0);
|
||||
if (priv->module == NULL)
|
||||
goto open_failed;
|
||||
|
||||
names_not_found = g_array_new (TRUE, FALSE, sizeof (gchar *));
|
||||
|
||||
for (i = 0; symbols[i].name != NULL; i++) {
|
||||
const GstDynSymSpec *s = &symbols[i];
|
||||
if (!g_module_symbol (priv->module, s->name,
|
||||
(gpointer *) (((guint8 *) api) + s->offset)) && s->is_required) {
|
||||
g_array_append_val (names_not_found, s->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (names_not_found->len > 0)
|
||||
goto one_or_more_name_not_found;
|
||||
|
||||
g_array_free (names_not_found, TRUE);
|
||||
|
||||
return api;
|
||||
|
||||
/* ERRORS */
|
||||
open_failed:
|
||||
{
|
||||
gchar *basename;
|
||||
|
||||
basename = g_path_get_basename (filename);
|
||||
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
|
||||
"failed to open %s", basename);
|
||||
g_free (basename);
|
||||
|
||||
goto any_error;
|
||||
}
|
||||
one_or_more_name_not_found:
|
||||
{
|
||||
gchar *basename, *names_joined;
|
||||
|
||||
basename = g_path_get_basename (filename);
|
||||
names_joined = g_strjoinv (", ", (gchar **) names_not_found->data);
|
||||
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
|
||||
"missing %u symbol%s in %s: %s",
|
||||
names_not_found->len, (names_not_found->len == 1) ? "" : "s",
|
||||
basename, names_joined);
|
||||
g_free (names_joined);
|
||||
g_free (basename);
|
||||
g_array_free (names_not_found, TRUE);
|
||||
|
||||
goto any_error;
|
||||
}
|
||||
any_error:
|
||||
{
|
||||
g_object_unref (api);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_DYN_API_H__
|
||||
#define __GST_DYN_API_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_DYN_API \
|
||||
(gst_dyn_api_get_type ())
|
||||
#define GST_DYN_API(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DYN_API, GstDynApi))
|
||||
#define GST_DYN_API_CAST(obj) \
|
||||
((GstDynApi *) (obj))
|
||||
#define GST_DYN_API_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DYN_API, GstDynApiClass))
|
||||
#define GST_IS_DYN_API(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DYN_API))
|
||||
#define GST_IS_DYN_API_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DYN_API))
|
||||
|
||||
#define GST_DYN_SYM_SPEC(type, name) \
|
||||
{ G_STRINGIFY (name), G_STRUCT_OFFSET (type, name), TRUE }
|
||||
#define GST_DYN_SYM_SPEC_OPTIONAL(type, name) \
|
||||
{ G_STRINGIFY (name), G_STRUCT_OFFSET (type, name), FALSE }
|
||||
|
||||
typedef struct _GstDynApi GstDynApi;
|
||||
typedef struct _GstDynApiClass GstDynApiClass;
|
||||
typedef struct _GstDynApiPrivate GstDynApiPrivate;
|
||||
|
||||
struct _GstDynApi
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GstDynApiPrivate * priv;
|
||||
};
|
||||
|
||||
struct _GstDynApiClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_dyn_api_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,234 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "mioapi.h"
|
||||
|
||||
#include "dynapi-internal.h"
|
||||
|
||||
#define MIO_FRAMEWORK_PATH "/System/Library/PrivateFrameworks/" \
|
||||
"CoreMediaIOServices.framework/CoreMediaIOServices"
|
||||
|
||||
GType gst_mio_api_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GstMIOApi, gst_mio_api, GST_TYPE_DYN_API);
|
||||
|
||||
static void
|
||||
gst_mio_api_init (GstMIOApi * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_api_class_init (GstMIOApiClass * klass)
|
||||
{
|
||||
}
|
||||
|
||||
#define SYM_SPEC(name) GST_DYN_SYM_SPEC (GstMIOApi, name)
|
||||
|
||||
GstMIOApi *
|
||||
gst_mio_api_obtain (GError ** error)
|
||||
{
|
||||
static const GstDynSymSpec symbols[] = {
|
||||
SYM_SPEC (TundraGraphCreate),
|
||||
SYM_SPEC (TundraGraphRelease),
|
||||
SYM_SPEC (TundraGraphCreateNode),
|
||||
SYM_SPEC (TundraGraphGetNodeInfo),
|
||||
SYM_SPEC (TundraGraphSetProperty),
|
||||
SYM_SPEC (TundraGraphConnectNodeInput),
|
||||
SYM_SPEC (TundraGraphInitialize),
|
||||
SYM_SPEC (TundraGraphUninitialize),
|
||||
SYM_SPEC (TundraGraphStart),
|
||||
SYM_SPEC (TundraGraphStop),
|
||||
|
||||
SYM_SPEC (TundraObjectGetPropertyDataSize),
|
||||
SYM_SPEC (TundraObjectGetPropertyData),
|
||||
SYM_SPEC (TundraObjectIsPropertySettable),
|
||||
SYM_SPEC (TundraObjectSetPropertyData),
|
||||
|
||||
SYM_SPEC (kTundraSampleBufferAttachmentKey_SequenceNumber),
|
||||
SYM_SPEC (kTundraSampleBufferAttachmentKey_HostTime),
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
return _gst_dyn_api_new (gst_mio_api_get_type (), MIO_FRAMEWORK_PATH, symbols,
|
||||
error);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_mio_object_get_pointer (gint obj, TundraTargetSpec * pspec, GstMIOApi * mio)
|
||||
{
|
||||
gpointer ptr;
|
||||
guint sz;
|
||||
TundraStatus status;
|
||||
|
||||
sz = sizeof (ptr);
|
||||
status = mio->TundraObjectGetPropertyData (obj, pspec, 0, NULL, &sz, &ptr);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
|
||||
return ptr;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gst_mio_object_get_string (gint obj, TundraTargetSpec * pspec, GstMIOApi * mio)
|
||||
{
|
||||
gchar *result = NULL;
|
||||
CFStringRef str;
|
||||
guint size;
|
||||
TundraStatus status;
|
||||
CFRange range;
|
||||
|
||||
size = sizeof (str);
|
||||
status = mio->TundraObjectGetPropertyData (obj, pspec, 0, NULL, &size, &str);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
|
||||
range.location = 0;
|
||||
range.length = CFStringGetLength (str);
|
||||
result = g_malloc0 (range.length + 1);
|
||||
CFStringGetBytes (str, range, kCFStringEncodingUTF8, 0, FALSE,
|
||||
(UInt8 *) result, range.length, NULL);
|
||||
CFRelease (str);
|
||||
|
||||
return result;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
guint32
|
||||
gst_mio_object_get_uint32 (gint obj, TundraTargetSpec * pspec, GstMIOApi * mio)
|
||||
{
|
||||
guint32 val;
|
||||
guint size;
|
||||
TundraStatus status;
|
||||
|
||||
size = sizeof (val);
|
||||
status = mio->TundraObjectGetPropertyData (obj, pspec, 0, NULL, &size, &val);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
|
||||
return val;
|
||||
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
GArray *
|
||||
gst_mio_object_get_array (gint obj, TundraTargetSpec * pspec,
|
||||
guint element_size, GstMIOApi * mio)
|
||||
{
|
||||
return gst_mio_object_get_array_full (obj, pspec, 0, NULL, element_size, mio);
|
||||
}
|
||||
|
||||
GArray *
|
||||
gst_mio_object_get_array_full (gint obj, TundraTargetSpec * pspec,
|
||||
guint ctx_size, gpointer ctx, guint element_size, GstMIOApi * mio)
|
||||
{
|
||||
GArray *arr = NULL;
|
||||
guint size, num_elements;
|
||||
TundraStatus status;
|
||||
|
||||
status = mio->TundraObjectGetPropertyDataSize (obj, pspec, ctx_size, ctx,
|
||||
&size);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
else if (size % element_size != 0)
|
||||
goto error;
|
||||
|
||||
num_elements = size / element_size;
|
||||
arr = g_array_sized_new (FALSE, TRUE, element_size, num_elements);
|
||||
g_array_set_size (arr, num_elements);
|
||||
|
||||
status = mio->TundraObjectGetPropertyData (obj, pspec, ctx_size, ctx,
|
||||
&size, arr->data);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
|
||||
return arr;
|
||||
|
||||
error:
|
||||
if (arr != NULL)
|
||||
g_array_free (arr, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gst_mio_object_get_fourcc (gint obj, TundraTargetSpec * pspec, GstMIOApi * mio)
|
||||
{
|
||||
guint32 fcc;
|
||||
guint size;
|
||||
TundraStatus status;
|
||||
|
||||
size = sizeof (fcc);
|
||||
status = mio->TundraObjectGetPropertyData (obj, pspec, 0, NULL, &size, &fcc);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
|
||||
return gst_mio_fourcc_to_string (fcc);
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_mio_object_get_raw (gint obj, TundraTargetSpec * pspec, guint * size,
|
||||
GstMIOApi * mio)
|
||||
{
|
||||
gpointer data = NULL;
|
||||
guint sz;
|
||||
TundraStatus status;
|
||||
|
||||
status = mio->TundraObjectGetPropertyDataSize (obj, pspec, 0, NULL, &sz);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
|
||||
data = g_malloc0 (sz);
|
||||
|
||||
status = mio->TundraObjectGetPropertyData (obj, pspec, 0, NULL, &sz, data);
|
||||
if (status != kTundraSuccess)
|
||||
goto error;
|
||||
|
||||
if (size != NULL)
|
||||
*size = sz;
|
||||
return data;
|
||||
|
||||
error:
|
||||
g_free (data);
|
||||
if (size != NULL)
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gst_mio_fourcc_to_string (guint32 fcc)
|
||||
{
|
||||
gchar *result;
|
||||
|
||||
result = g_malloc0 (5);
|
||||
result[0] = (fcc >> 24) & 0xff;
|
||||
result[1] = (fcc >> 16) & 0xff;
|
||||
result[2] = (fcc >> 8) & 0xff;
|
||||
result[3] = (fcc >> 0) & 0xff;
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_MIO_API_H__
|
||||
#define __GST_MIO_API_H__
|
||||
|
||||
#include "cmapi.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstMIOApi GstMIOApi;
|
||||
typedef struct _GstMIOApiClass GstMIOApiClass;
|
||||
|
||||
#define TUNDRA_SYSTEM_OBJECT_ID 1
|
||||
|
||||
typedef int TundraObjectID;
|
||||
typedef int TundraDeviceID;
|
||||
typedef int TundraUnitID;
|
||||
|
||||
typedef enum _TundraStatus TundraStatus;
|
||||
typedef enum _TundraVendor TundraVendor;
|
||||
typedef enum _TundraScope TundraScope;
|
||||
typedef enum _TundraUnit TundraUnit;
|
||||
typedef enum _TundraProperty TundraProperty;
|
||||
|
||||
typedef enum _TundraDeviceTransportType TundraDeviceTransportType;
|
||||
|
||||
typedef struct _TundraTargetSpec TundraTargetSpec;
|
||||
typedef struct _TundraFramerate TundraFramerate;
|
||||
|
||||
typedef struct _TundraGraph TundraGraph;
|
||||
typedef struct _TundraNode TundraNode;
|
||||
|
||||
typedef struct _TundraOutputDelegate TundraOutputDelegate;
|
||||
|
||||
enum _TundraStatus
|
||||
{
|
||||
kTundraSuccess = 0,
|
||||
kTundraNotSupported = -67456
|
||||
};
|
||||
|
||||
enum _TundraVendor
|
||||
{
|
||||
kTundraVendorApple = 'appl'
|
||||
};
|
||||
|
||||
enum _TundraScope
|
||||
{
|
||||
kTundraScopeGlobal = 'glob',
|
||||
kTundraScopeDAL = 'dal ',
|
||||
kTundraScope2PRC = '2prc', /* TODO: Investigate this one */
|
||||
kTundraScopeInput = 'inpt',
|
||||
kTundraScopeVSyn = 'vsyn'
|
||||
};
|
||||
|
||||
enum _TundraUnit
|
||||
{
|
||||
kTundraUnitInput = 'tinp',
|
||||
kTundraUnitOutput = 'tout',
|
||||
kTundraUnitSync = 'tefc'
|
||||
};
|
||||
|
||||
enum _TundraProperty
|
||||
{
|
||||
kTundraSystemPropertyDevices = 'dev#',
|
||||
|
||||
kTundraObjectPropertyClass = 'clas',
|
||||
kTundraObjectPropertyCreator = 'oplg',
|
||||
kTundraObjectPropertyName = 'lnam',
|
||||
kTundraObjectPropertyUID = 'uid ',
|
||||
kTundraObjectPropertyVendor = 'lmak',
|
||||
|
||||
kTundraDevicePropertyConfigApp = 'capp', /* CFString: com.apple.mediaio.TundraDeviceSetup */
|
||||
kTundraDevicePropertyExclusiveMode = 'ixna',
|
||||
kTundraDevicePropertyHogMode = 'oink',
|
||||
kTundraDevicePropertyModelUID = 'muid',
|
||||
kTundraDevicePropertyStreams = 'stm#',
|
||||
kTundraDevicePropertySuspendedByUser = 'sbyu',
|
||||
kTundraDevicePropertyTransportType = 'tran',
|
||||
|
||||
kTundraStreamPropertyFormatDescriptions = 'pfta',
|
||||
kTundraStreamPropertyFormatDescription = 'pft ',
|
||||
kTundraStreamPropertyFrameRates = 'nfr#',
|
||||
kTundraStreamPropertyFrameRate = 'nfrt'
|
||||
};
|
||||
|
||||
struct _TundraTargetSpec
|
||||
{
|
||||
FourCharCode name;
|
||||
FourCharCode scope;
|
||||
FourCharCode vendor;
|
||||
FourCharCode unk1;
|
||||
FourCharCode unk2;
|
||||
};
|
||||
|
||||
struct _TundraFramerate
|
||||
{
|
||||
gdouble value;
|
||||
};
|
||||
|
||||
enum _TundraUnitProperty
|
||||
{
|
||||
kTundraInputPropertyDeviceID = 302,
|
||||
|
||||
kTundraOutputPropertyDelegate = 5903,
|
||||
|
||||
kTundraInputUnitProperty_SourcePath = 6780,
|
||||
|
||||
kTundraSyncPropertyClockProvider = 7100,
|
||||
kTundraSyncPropertyMasterSynchronizer = 7102,
|
||||
kTundraSyncPropertySynchronizationDirection = 7104
|
||||
};
|
||||
|
||||
enum _TundraDeviceTransportType
|
||||
{
|
||||
kTundraDeviceTransportInvalid = 0,
|
||||
kTundraDeviceTransportBuiltin = 'bltn',
|
||||
kTundraDeviceTransportScreen = 'scrn',
|
||||
kTundraDeviceTransportUSB = 'usb ',
|
||||
};
|
||||
|
||||
typedef TundraStatus (* TundraOutputRenderFunc) (gpointer instance,
|
||||
gpointer unk1, gpointer unk2, gpointer unk3, CMSampleBufferRef sampleBuf);
|
||||
typedef TundraStatus (* TundraOutputInitializeFunc) (gpointer instance);
|
||||
typedef TundraStatus (* TundraOutputUninitializeFunc) (gpointer instance);
|
||||
typedef TundraStatus (* TundraOutputStartFunc) (gpointer instance);
|
||||
typedef TundraStatus (* TundraOutputStopFunc) (gpointer instance);
|
||||
typedef TundraStatus (* TundraOutputResetFunc) (gpointer instance);
|
||||
typedef TundraStatus (* TundraOutputDeallocateFunc) (gpointer instance);
|
||||
typedef gboolean (* TundraOutputCanRenderNowFunc) (gpointer instance,
|
||||
guint * unk);
|
||||
typedef CFArrayRef (* TundraOutputAvailableFormatsFunc) (gpointer instance,
|
||||
gboolean ensureOnly);
|
||||
typedef TundraStatus (* TundraOutputCopyClockFunc) (gpointer instance);
|
||||
typedef TundraStatus (* TundraOutputGetPropertyInfoFunc) (gpointer instance,
|
||||
guint propId);
|
||||
typedef TundraStatus (* TundraOutputGetPropertyFunc) (gpointer instance,
|
||||
guint propId);
|
||||
typedef TundraStatus (* TundraOutputSetPropertyFunc) (gpointer instance,
|
||||
guint propId);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct _TundraOutputDelegate
|
||||
{
|
||||
int unk1;
|
||||
gpointer instance;
|
||||
TundraOutputRenderFunc Render;
|
||||
TundraOutputInitializeFunc Initialize;
|
||||
TundraOutputUninitializeFunc Uninitialize;
|
||||
TundraOutputStartFunc Start;
|
||||
TundraOutputStopFunc Stop;
|
||||
TundraOutputResetFunc Reset;
|
||||
TundraOutputDeallocateFunc Deallocate;
|
||||
TundraOutputCanRenderNowFunc CanRenderNow;
|
||||
TundraOutputAvailableFormatsFunc AvailableFormats;
|
||||
TundraOutputCopyClockFunc CopyClock;
|
||||
TundraOutputGetPropertyInfoFunc GetPropertyInfo;
|
||||
TundraOutputGetPropertyFunc GetProperty;
|
||||
TundraOutputSetPropertyFunc SetProperty;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct _GstMIOApi
|
||||
{
|
||||
GstDynApi parent;
|
||||
|
||||
TundraStatus (* TundraGraphCreate) (CFAllocatorRef allocator,
|
||||
TundraGraph ** graph);
|
||||
void (* TundraGraphRelease) (TundraGraph * graph);
|
||||
TundraStatus (* TundraGraphCreateNode) (TundraGraph * graph,
|
||||
gint nodeId, UInt32 unk1, UInt32 unk2, TundraTargetSpec * spec,
|
||||
UInt32 unk3, TundraUnitID * node);
|
||||
TundraStatus (* TundraGraphGetNodeInfo) (TundraGraph * graph,
|
||||
gint nodeId, UInt32 unk1, UInt32 unk2, UInt32 unk3, UInt32 unk4,
|
||||
gpointer * info);
|
||||
TundraStatus (* TundraGraphSetProperty) (TundraGraph * graph,
|
||||
gint nodeId, UInt32 unk1, guint propId, UInt32 unk2, UInt32 unk3,
|
||||
gpointer data, guint size);
|
||||
TundraStatus (* TundraGraphConnectNodeInput) (TundraGraph * graph,
|
||||
TundraUnitID from_node, guint from_bus,
|
||||
TundraUnitID to_node, guint to_bus);
|
||||
TundraStatus (* TundraGraphInitialize) (TundraGraph * graph);
|
||||
TundraStatus (* TundraGraphUninitialize) (TundraGraph * graph);
|
||||
TundraStatus (* TundraGraphStart) (TundraGraph * graph);
|
||||
TundraStatus (* TundraGraphStop) (TundraGraph * graph);
|
||||
|
||||
TundraStatus (* TundraObjectGetPropertyDataSize) (TundraObjectID obj,
|
||||
TundraTargetSpec * spec, UInt32 contextSize, void * context, guint * size);
|
||||
TundraStatus (* TundraObjectGetPropertyData) (TundraObjectID obj,
|
||||
TundraTargetSpec * spec, UInt32 contextSize, void * context, guint * size,
|
||||
gpointer data);
|
||||
TundraStatus (* TundraObjectIsPropertySettable) (TundraObjectID obj,
|
||||
TundraTargetSpec * spec, Boolean *isSettable);
|
||||
TundraStatus (* TundraObjectSetPropertyData) (TundraObjectID obj,
|
||||
TundraTargetSpec * spec, gpointer unk1, gpointer unk2, guint size,
|
||||
gpointer data);
|
||||
|
||||
CFStringRef * kTundraSampleBufferAttachmentKey_SequenceNumber;
|
||||
CFStringRef * kTundraSampleBufferAttachmentKey_HostTime;
|
||||
};
|
||||
|
||||
struct _GstMIOApiClass
|
||||
{
|
||||
GstDynApiClass parent_class;
|
||||
};
|
||||
|
||||
GstMIOApi * gst_mio_api_obtain (GError ** error);
|
||||
|
||||
gpointer gst_mio_object_get_pointer (gint obj, TundraTargetSpec * pspec,
|
||||
GstMIOApi * mio);
|
||||
gchar * gst_mio_object_get_string (gint obj, TundraTargetSpec * pspec,
|
||||
GstMIOApi * mio);
|
||||
guint32 gst_mio_object_get_uint32 (gint obj, TundraTargetSpec * pspec,
|
||||
GstMIOApi * mio);
|
||||
gchar * gst_mio_object_get_fourcc (gint obj, TundraTargetSpec * pspec,
|
||||
GstMIOApi * mio);
|
||||
GArray * gst_mio_object_get_array (gint obj, TundraTargetSpec * pspec,
|
||||
guint element_size, GstMIOApi * mio);
|
||||
GArray * gst_mio_object_get_array_full (gint obj, TundraTargetSpec * pspec,
|
||||
guint ctx_size, gpointer ctx, guint element_size, GstMIOApi * mio);
|
||||
gpointer gst_mio_object_get_raw (gint obj, TundraTargetSpec * pspec,
|
||||
guint * size, GstMIOApi * mio);
|
||||
|
||||
gchar * gst_mio_fourcc_to_string (guint32 fcc);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,846 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
* 2009 Knut Inge Hvidsten <knuhvids@cisco.com>
|
||||
*
|
||||
* 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 "miovideodevice.h"
|
||||
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (gst_mio_video_src_debug);
|
||||
#define GST_CAT_DEFAULT gst_mio_video_src_debug
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CONTEXT,
|
||||
PROP_HANDLE,
|
||||
PROP_UID,
|
||||
PROP_NAME,
|
||||
PROP_TRANSPORT
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GstMIOVideoDevice, gst_mio_video_device, G_TYPE_OBJECT);
|
||||
|
||||
typedef struct _GstMIOVideoFormat GstMIOVideoFormat;
|
||||
typedef struct _GstMIOSetFormatCtx GstMIOSetFormatCtx;
|
||||
typedef struct _GstMIOFindRateCtx GstMIOFindRateCtx;
|
||||
|
||||
struct _GstMIOVideoFormat
|
||||
{
|
||||
TundraObjectID stream;
|
||||
CMFormatDescriptionRef desc;
|
||||
|
||||
UInt32 type;
|
||||
CMVideoDimensions dim;
|
||||
};
|
||||
|
||||
struct _GstMIOSetFormatCtx
|
||||
{
|
||||
UInt32 format;
|
||||
gint width, height;
|
||||
gint fps_n, fps_d;
|
||||
gboolean success;
|
||||
};
|
||||
|
||||
struct _GstMIOFindRateCtx
|
||||
{
|
||||
gdouble needle;
|
||||
gdouble closest_match;
|
||||
gboolean success;
|
||||
};
|
||||
|
||||
static void gst_mio_video_device_collect_format (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, gpointer user_data);
|
||||
static GstStructure *gst_mio_video_device_format_basics_to_structure
|
||||
(GstMIOVideoDevice * self, GstMIOVideoFormat * format);
|
||||
static gboolean gst_mio_video_device_add_framerates_to_structure
|
||||
(GstMIOVideoDevice * self, GstMIOVideoFormat * format, GstStructure * s);
|
||||
static void gst_mio_video_device_add_pixel_aspect_to_structure
|
||||
(GstMIOVideoDevice * self, GstMIOVideoFormat * format, GstStructure * s);
|
||||
|
||||
static void gst_mio_video_device_append_framerate (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, TundraFramerate * rate, gpointer user_data);
|
||||
static void gst_mio_video_device_framerate_to_fraction_value
|
||||
(TundraFramerate * rate, GValue * fract);
|
||||
static gdouble gst_mio_video_device_round_to_whole_hundreths (gdouble value);
|
||||
static void gst_mio_video_device_guess_pixel_aspect_ratio
|
||||
(gint width, gint height, gint * par_width, gint * par_height);
|
||||
|
||||
static void gst_mio_video_device_activate_matching_format
|
||||
(GstMIOVideoDevice * self, GstMIOVideoFormat * format, gpointer user_data);
|
||||
static void gst_mio_video_device_find_closest_framerate
|
||||
(GstMIOVideoDevice * self, GstMIOVideoFormat * format,
|
||||
TundraFramerate * rate, gpointer user_data);
|
||||
|
||||
typedef void (*GstMIOVideoDeviceEachFormatFunc) (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, gpointer user_data);
|
||||
typedef void (*GstMIOVideoDeviceEachFramerateFunc) (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, TundraFramerate * rate, gpointer user_data);
|
||||
static void gst_mio_video_device_formats_foreach (GstMIOVideoDevice * self,
|
||||
GstMIOVideoDeviceEachFormatFunc func, gpointer user_data);
|
||||
static void gst_mio_video_device_format_framerates_foreach
|
||||
(GstMIOVideoDevice * self, GstMIOVideoFormat * format,
|
||||
GstMIOVideoDeviceEachFramerateFunc func, gpointer user_data);
|
||||
|
||||
static gint gst_mio_video_device_compare (GstMIOVideoDevice * a,
|
||||
GstMIOVideoDevice * b);
|
||||
static gint gst_mio_video_device_calculate_score (GstMIOVideoDevice * device);
|
||||
|
||||
static void
|
||||
gst_mio_video_device_init (GstMIOVideoDevice * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_dispose (GObject * object)
|
||||
{
|
||||
GstMIOVideoDevice *self = GST_MIO_VIDEO_DEVICE_CAST (object);
|
||||
|
||||
if (self->cached_caps != NULL) {
|
||||
gst_caps_unref (self->cached_caps);
|
||||
self->cached_caps = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gst_mio_video_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_finalize (GObject * object)
|
||||
{
|
||||
GstMIOVideoDevice *self = GST_MIO_VIDEO_DEVICE_CAST (object);
|
||||
|
||||
g_free (self->cached_uid);
|
||||
g_free (self->cached_name);
|
||||
|
||||
G_OBJECT_CLASS (gst_mio_video_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstMIOVideoDevice *self = GST_MIO_VIDEO_DEVICE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_pointer (value, self->ctx);
|
||||
break;
|
||||
case PROP_HANDLE:
|
||||
g_value_set_int (value, gst_mio_video_device_get_handle (self));
|
||||
break;
|
||||
case PROP_UID:
|
||||
g_value_set_string (value, gst_mio_video_device_get_uid (self));
|
||||
break;
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, gst_mio_video_device_get_name (self));
|
||||
break;
|
||||
case PROP_TRANSPORT:
|
||||
g_value_set_uint (value, gst_mio_video_device_get_transport_type (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstMIOVideoDevice *self = GST_MIO_VIDEO_DEVICE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CONTEXT:
|
||||
self->ctx = g_value_get_pointer (value);
|
||||
break;
|
||||
case PROP_HANDLE:
|
||||
self->handle = g_value_get_int (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TundraObjectID
|
||||
gst_mio_video_device_get_handle (GstMIOVideoDevice * self)
|
||||
{
|
||||
return self->handle;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gst_mio_video_device_get_uid (GstMIOVideoDevice * self)
|
||||
{
|
||||
if (self->cached_uid == NULL) {
|
||||
TundraTargetSpec pspec = { 0, };
|
||||
|
||||
pspec.name = kTundraObjectPropertyUID;
|
||||
pspec.scope = kTundraScopeGlobal;
|
||||
self->cached_uid =
|
||||
gst_mio_object_get_string (self->handle, &pspec, self->ctx->mio);
|
||||
}
|
||||
|
||||
return self->cached_uid;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gst_mio_video_device_get_name (GstMIOVideoDevice * self)
|
||||
{
|
||||
if (self->cached_name == NULL) {
|
||||
TundraTargetSpec pspec = { 0, };
|
||||
|
||||
pspec.name = kTundraObjectPropertyName;
|
||||
pspec.scope = kTundraScopeGlobal;
|
||||
self->cached_name =
|
||||
gst_mio_object_get_string (self->handle, &pspec, self->ctx->mio);
|
||||
}
|
||||
|
||||
return self->cached_name;
|
||||
}
|
||||
|
||||
TundraDeviceTransportType
|
||||
gst_mio_video_device_get_transport_type (GstMIOVideoDevice * self)
|
||||
{
|
||||
if (self->cached_transport == kTundraDeviceTransportInvalid) {
|
||||
TundraTargetSpec pspec = { 0, };
|
||||
|
||||
pspec.name = kTundraDevicePropertyTransportType;
|
||||
pspec.scope = kTundraScopeGlobal;
|
||||
self->cached_transport =
|
||||
gst_mio_object_get_uint32 (self->handle, &pspec, self->ctx->mio);
|
||||
}
|
||||
|
||||
return self->cached_transport;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_mio_video_device_open (GstMIOVideoDevice * self)
|
||||
{
|
||||
/* nothing for now */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_mio_video_device_close (GstMIOVideoDevice * self)
|
||||
{
|
||||
/* nothing for now */
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_mio_video_device_get_available_caps (GstMIOVideoDevice * self)
|
||||
{
|
||||
if (self->cached_caps == NULL) {
|
||||
GstCaps *caps;
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
gst_mio_video_device_formats_foreach (self,
|
||||
gst_mio_video_device_collect_format, caps);
|
||||
|
||||
self->cached_caps = caps;
|
||||
}
|
||||
|
||||
return self->cached_caps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_collect_format (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, gpointer user_data)
|
||||
{
|
||||
GstCaps *caps = user_data;
|
||||
GstStructure *s;
|
||||
|
||||
s = gst_mio_video_device_format_basics_to_structure (self, format);
|
||||
if (s == NULL)
|
||||
goto unsupported_format;
|
||||
|
||||
if (!gst_mio_video_device_add_framerates_to_structure (self, format, s))
|
||||
goto no_framerates;
|
||||
|
||||
gst_mio_video_device_add_pixel_aspect_to_structure (self, format, s);
|
||||
|
||||
gst_caps_append_structure (caps, s);
|
||||
|
||||
return;
|
||||
|
||||
/* ERRORS */
|
||||
unsupported_format:
|
||||
{
|
||||
gchar *fcc;
|
||||
|
||||
fcc = gst_mio_fourcc_to_string (format->type);
|
||||
GST_WARNING ("skipping unsupported format %s", fcc);
|
||||
g_free (fcc);
|
||||
|
||||
return;
|
||||
}
|
||||
no_framerates:
|
||||
{
|
||||
GST_WARNING ("no framerates?");
|
||||
|
||||
gst_structure_free (s);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStructure *
|
||||
gst_mio_video_device_format_basics_to_structure (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format)
|
||||
{
|
||||
GstStructure *s;
|
||||
|
||||
switch (format->type) {
|
||||
case kCVPixelFormatType_422YpCbCr8:
|
||||
case kCVPixelFormatType_422YpCbCr8Deprecated:
|
||||
{
|
||||
guint fcc;
|
||||
|
||||
if (format->type == kCVPixelFormatType_422YpCbCr8)
|
||||
fcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
|
||||
else
|
||||
fcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
|
||||
|
||||
s = gst_structure_new ("video/x-raw-yuv",
|
||||
"format", GST_TYPE_FOURCC, fcc,
|
||||
"width", G_TYPE_INT, format->dim.width,
|
||||
"height", G_TYPE_INT, format->dim.height, NULL);
|
||||
break;
|
||||
}
|
||||
case kFigVideoCodecType_JPEG_OpenDML:
|
||||
{
|
||||
s = gst_structure_new ("image/jpeg",
|
||||
"width", G_TYPE_INT, format->dim.width,
|
||||
"height", G_TYPE_INT, format->dim.height, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
s = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_mio_video_device_add_framerates_to_structure (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, GstStructure * s)
|
||||
{
|
||||
GValue rates = { 0, };
|
||||
const GValue *rates_value;
|
||||
|
||||
g_value_init (&rates, GST_TYPE_LIST);
|
||||
|
||||
gst_mio_video_device_format_framerates_foreach (self, format,
|
||||
gst_mio_video_device_append_framerate, &rates);
|
||||
if (gst_value_list_get_size (&rates) == 0)
|
||||
goto no_framerates;
|
||||
|
||||
if (gst_value_list_get_size (&rates) > 1)
|
||||
rates_value = &rates;
|
||||
else
|
||||
rates_value = gst_value_list_get_value (&rates, 0);
|
||||
gst_structure_set_value (s, "framerate", rates_value);
|
||||
|
||||
g_value_unset (&rates);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_framerates:
|
||||
{
|
||||
g_value_unset (&rates);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_add_pixel_aspect_to_structure (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, GstStructure * s)
|
||||
{
|
||||
gint par_width, par_height;
|
||||
|
||||
gst_mio_video_device_guess_pixel_aspect_ratio
|
||||
(format->dim.width, format->dim.height, &par_width, &par_height);
|
||||
|
||||
gst_structure_set (s, "pixel-aspect-ratio",
|
||||
GST_TYPE_FRACTION, par_width, par_height, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_append_framerate (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, TundraFramerate * rate, gpointer user_data)
|
||||
{
|
||||
GValue *rates = user_data;
|
||||
GValue value = { 0, };
|
||||
|
||||
g_value_init (&value, GST_TYPE_FRACTION);
|
||||
gst_mio_video_device_framerate_to_fraction_value (rate, &value);
|
||||
gst_value_list_append_value (rates, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_framerate_to_fraction_value (TundraFramerate * rate,
|
||||
GValue * fract)
|
||||
{
|
||||
gdouble rounded;
|
||||
gint n, d;
|
||||
|
||||
rounded = gst_mio_video_device_round_to_whole_hundreths (rate->value);
|
||||
gst_util_double_to_fraction (rounded, &n, &d);
|
||||
gst_value_set_fraction (fract, n, d);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
gst_mio_video_device_round_to_whole_hundreths (gdouble value)
|
||||
{
|
||||
gdouble m, x, y, z;
|
||||
|
||||
m = 0.01;
|
||||
x = value;
|
||||
y = floor ((x / m) + 0.5);
|
||||
z = y * m;
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_guess_pixel_aspect_ratio (gint width, gint height,
|
||||
gint * par_width, gint * par_height)
|
||||
{
|
||||
/*
|
||||
* As we dont have access to the actual pixel aspect, we will try to do a
|
||||
* best-effort guess. The guess is based on most sensors being either 4/3
|
||||
* or 16/9, and most pixel aspects being close to 1/1.
|
||||
*/
|
||||
|
||||
if (width == 768 && height == 448) { /* special case for w448p */
|
||||
*par_width = 28;
|
||||
*par_height = 27;
|
||||
} else {
|
||||
if (((gdouble) width / (gdouble) height) < 1.2778) {
|
||||
*par_width = 12;
|
||||
*par_height = 11;
|
||||
} else {
|
||||
*par_width = 1;
|
||||
*par_height = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_mio_video_device_set_caps (GstMIOVideoDevice * self, GstCaps * caps)
|
||||
{
|
||||
GstVideoFormat format;
|
||||
GstMIOSetFormatCtx ctx = { 0, };
|
||||
|
||||
if (gst_video_format_parse_caps (caps, &format, &ctx.width, &ctx.height)) {
|
||||
if (format == GST_VIDEO_FORMAT_UYVY)
|
||||
ctx.format = kCVPixelFormatType_422YpCbCr8;
|
||||
else if (format == GST_VIDEO_FORMAT_YUY2)
|
||||
ctx.format = kCVPixelFormatType_422YpCbCr8Deprecated;
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
} else {
|
||||
GstStructure *s;
|
||||
|
||||
s = gst_caps_get_structure (caps, 0);
|
||||
g_assert (gst_structure_has_name (s, "image/jpeg"));
|
||||
gst_structure_get_int (s, "width", &ctx.width);
|
||||
gst_structure_get_int (s, "height", &ctx.height);
|
||||
|
||||
ctx.format = kFigVideoCodecType_JPEG_OpenDML;
|
||||
}
|
||||
|
||||
gst_video_parse_caps_framerate (caps, &ctx.fps_n, &ctx.fps_d);
|
||||
|
||||
gst_mio_video_device_formats_foreach (self,
|
||||
gst_mio_video_device_activate_matching_format, &ctx);
|
||||
|
||||
return ctx.success;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_activate_matching_format (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, gpointer user_data)
|
||||
{
|
||||
GstMIOSetFormatCtx *ctx = user_data;
|
||||
GstMIOFindRateCtx find_ctx;
|
||||
TundraTargetSpec spec = { 0, };
|
||||
TundraStatus status;
|
||||
|
||||
if (format->type != ctx->format)
|
||||
return;
|
||||
else if (format->dim.width != ctx->width)
|
||||
return;
|
||||
else if (format->dim.height != ctx->height)
|
||||
return;
|
||||
|
||||
find_ctx.needle = (gdouble) ctx->fps_n / (gdouble) ctx->fps_d;
|
||||
find_ctx.closest_match = 0.0;
|
||||
find_ctx.success = FALSE;
|
||||
gst_mio_video_device_format_framerates_foreach (self, format,
|
||||
gst_mio_video_device_find_closest_framerate, &find_ctx);
|
||||
if (!find_ctx.success)
|
||||
goto no_matching_framerate_found;
|
||||
|
||||
spec.scope = kTundraScopeInput;
|
||||
|
||||
spec.name = kTundraStreamPropertyFormatDescription;
|
||||
status = self->ctx->mio->TundraObjectSetPropertyData (format->stream, &spec,
|
||||
NULL, NULL, sizeof (format->desc), &format->desc);
|
||||
if (status != kTundraSuccess)
|
||||
goto failed_to_set_format;
|
||||
|
||||
spec.name = kTundraStreamPropertyFrameRate;
|
||||
status = self->ctx->mio->TundraObjectSetPropertyData (format->stream, &spec,
|
||||
NULL, NULL, sizeof (find_ctx.closest_match), &find_ctx.closest_match);
|
||||
if (status != kTundraSuccess)
|
||||
goto failed_to_set_framerate;
|
||||
|
||||
self->selected_format = format->desc;
|
||||
self->selected_fps_n = ctx->fps_n;
|
||||
self->selected_fps_d = ctx->fps_d;
|
||||
|
||||
ctx->success = TRUE;
|
||||
return;
|
||||
|
||||
/* ERRORS */
|
||||
no_matching_framerate_found:
|
||||
{
|
||||
GST_ERROR ("no matching framerate found");
|
||||
return;
|
||||
}
|
||||
failed_to_set_format:
|
||||
{
|
||||
GST_ERROR ("failed to set format: 0x%08x", status);
|
||||
return;
|
||||
}
|
||||
failed_to_set_framerate:
|
||||
{
|
||||
GST_ERROR ("failed to set framerate: 0x%08x", status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_find_closest_framerate (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, TundraFramerate * rate, gpointer user_data)
|
||||
{
|
||||
GstMIOFindRateCtx *ctx = user_data;
|
||||
|
||||
if (fabs (rate->value - ctx->needle) <= 0.1) {
|
||||
ctx->closest_match = rate->value;
|
||||
ctx->success = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CMFormatDescriptionRef
|
||||
gst_mio_video_device_get_selected_format (GstMIOVideoDevice * self)
|
||||
{
|
||||
return self->selected_format;
|
||||
}
|
||||
|
||||
GstClockTime
|
||||
gst_mio_video_device_get_duration (GstMIOVideoDevice * self)
|
||||
{
|
||||
return gst_util_uint64_scale_int (GST_SECOND,
|
||||
self->selected_fps_d, self->selected_fps_n);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_formats_foreach (GstMIOVideoDevice * self,
|
||||
GstMIOVideoDeviceEachFormatFunc func, gpointer user_data)
|
||||
{
|
||||
GstCMApi *cm = self->ctx->cm;
|
||||
GstMIOApi *mio = self->ctx->mio;
|
||||
TundraTargetSpec spec = { 0, };
|
||||
GArray *streams;
|
||||
guint stream_idx;
|
||||
|
||||
spec.name = kTundraDevicePropertyStreams;
|
||||
spec.scope = kTundraScopeInput;
|
||||
streams = gst_mio_object_get_array (self->handle, &spec,
|
||||
sizeof (TundraObjectID), mio);
|
||||
|
||||
/* TODO: We only consider the first stream for now */
|
||||
for (stream_idx = 0; stream_idx != MIN (streams->len, 1); stream_idx++) {
|
||||
TundraObjectID stream;
|
||||
CFArrayRef formats;
|
||||
CFIndex num_formats, fmt_idx;
|
||||
|
||||
stream = g_array_index (streams, TundraObjectID, stream_idx);
|
||||
|
||||
spec.name = kTundraStreamPropertyFormatDescriptions;
|
||||
spec.scope = kTundraScopeInput;
|
||||
|
||||
formats = gst_mio_object_get_pointer (stream, &spec, mio);
|
||||
num_formats = CFArrayGetCount (formats);
|
||||
|
||||
for (fmt_idx = 0; fmt_idx != num_formats; fmt_idx++) {
|
||||
GstMIOVideoFormat fmt;
|
||||
|
||||
fmt.stream = stream;
|
||||
fmt.desc = (CMFormatDescriptionRef)
|
||||
CFArrayGetValueAtIndex (formats, fmt_idx);
|
||||
if (cm->CMFormatDescriptionGetMediaType (fmt.desc) != kFigMediaTypeVideo)
|
||||
continue;
|
||||
fmt.type = cm->CMFormatDescriptionGetMediaSubType (fmt.desc);
|
||||
fmt.dim = cm->CMVideoFormatDescriptionGetDimensions (fmt.desc);
|
||||
|
||||
func (self, &fmt, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (streams, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_format_framerates_foreach (GstMIOVideoDevice * self,
|
||||
GstMIOVideoFormat * format, GstMIOVideoDeviceEachFramerateFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
TundraTargetSpec spec = { 0, };
|
||||
GArray *rates;
|
||||
guint rate_idx;
|
||||
|
||||
spec.name = kTundraStreamPropertyFrameRates;
|
||||
spec.scope = kTundraScopeInput;
|
||||
rates = gst_mio_object_get_array_full (format->stream, &spec,
|
||||
sizeof (format->desc), &format->desc, sizeof (TundraFramerate),
|
||||
self->ctx->mio);
|
||||
|
||||
for (rate_idx = 0; rate_idx != rates->len; rate_idx++) {
|
||||
TundraFramerate *rate;
|
||||
|
||||
rate = &g_array_index (rates, TundraFramerate, rate_idx);
|
||||
|
||||
func (self, format, rate, user_data);
|
||||
}
|
||||
|
||||
g_array_free (rates, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gst_mio_video_device_print_debug_info (GstMIOVideoDevice * self)
|
||||
{
|
||||
GstCMApi *cm = self->ctx->cm;
|
||||
GstMIOApi *mio = self->ctx->mio;
|
||||
TundraTargetSpec spec = { 0, };
|
||||
gchar *str;
|
||||
GArray *streams;
|
||||
guint stream_idx;
|
||||
|
||||
g_print ("Device %p with handle %d\n", self, self->handle);
|
||||
|
||||
spec.scope = kTundraScopeGlobal;
|
||||
|
||||
spec.name = kTundraObjectPropertyClass;
|
||||
str = gst_mio_object_get_fourcc (self->handle, &spec, mio);
|
||||
g_print (" Class: '%s'\n", str);
|
||||
g_free (str);
|
||||
|
||||
spec.name = kTundraObjectPropertyCreator;
|
||||
str = gst_mio_object_get_string (self->handle, &spec, mio);
|
||||
g_print (" Creator: \"%s\"\n", str);
|
||||
g_free (str);
|
||||
|
||||
spec.name = kTundraDevicePropertyModelUID;
|
||||
str = gst_mio_object_get_string (self->handle, &spec, mio);
|
||||
g_print (" Model UID: \"%s\"\n", str);
|
||||
g_free (str);
|
||||
|
||||
spec.name = kTundraDevicePropertyTransportType;
|
||||
str = gst_mio_object_get_fourcc (self->handle, &spec, mio);
|
||||
g_print (" Transport Type: '%s'\n", str);
|
||||
g_free (str);
|
||||
|
||||
g_print (" Streams:\n");
|
||||
spec.name = kTundraDevicePropertyStreams;
|
||||
spec.scope = kTundraScopeInput;
|
||||
streams = gst_mio_object_get_array (self->handle, &spec,
|
||||
sizeof (TundraObjectID), mio);
|
||||
for (stream_idx = 0; stream_idx != streams->len; stream_idx++) {
|
||||
TundraObjectID stream;
|
||||
CFArrayRef formats;
|
||||
CFIndex num_formats, fmt_idx;
|
||||
|
||||
stream = g_array_index (streams, TundraObjectID, stream_idx);
|
||||
|
||||
g_print (" stream[%u] = %d\n", stream_idx, stream);
|
||||
|
||||
spec.scope = kTundraScopeInput;
|
||||
spec.name = kTundraStreamPropertyFormatDescriptions;
|
||||
|
||||
formats = gst_mio_object_get_pointer (stream, &spec, mio);
|
||||
num_formats = CFArrayGetCount (formats);
|
||||
|
||||
g_print (" <%u formats>\n", (guint) num_formats);
|
||||
|
||||
for (fmt_idx = 0; fmt_idx != num_formats; fmt_idx++) {
|
||||
CMFormatDescriptionRef fmt;
|
||||
gchar *media_type;
|
||||
gchar *media_sub_type;
|
||||
CMVideoDimensions dim;
|
||||
GArray *rates;
|
||||
guint rate_idx;
|
||||
|
||||
fmt = CFArrayGetValueAtIndex (formats, fmt_idx);
|
||||
media_type = gst_mio_fourcc_to_string
|
||||
(cm->CMFormatDescriptionGetMediaType (fmt));
|
||||
media_sub_type = gst_mio_fourcc_to_string
|
||||
(cm->CMFormatDescriptionGetMediaSubType (fmt));
|
||||
dim = cm->CMVideoFormatDescriptionGetDimensions (fmt);
|
||||
|
||||
g_print (" format[%u]: MediaType='%s' MediaSubType='%s' %ux%u\n",
|
||||
(guint) fmt_idx, media_type, media_sub_type,
|
||||
(guint) dim.width, (guint) dim.height);
|
||||
|
||||
spec.name = kTundraStreamPropertyFrameRates;
|
||||
rates = gst_mio_object_get_array_full (stream, &spec, sizeof (fmt), &fmt,
|
||||
sizeof (TundraFramerate), mio);
|
||||
for (rate_idx = 0; rate_idx != rates->len; rate_idx++) {
|
||||
TundraFramerate *rate;
|
||||
|
||||
rate = &g_array_index (rates, TundraFramerate, rate_idx);
|
||||
g_print (" %f\n", rate->value);
|
||||
}
|
||||
g_array_free (rates, TRUE);
|
||||
|
||||
g_free (media_sub_type);
|
||||
g_free (media_type);
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (streams, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mio_video_device_class_init (GstMIOVideoDeviceClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gst_mio_video_device_dispose;
|
||||
gobject_class->finalize = gst_mio_video_device_finalize;
|
||||
gobject_class->get_property = gst_mio_video_device_get_property;
|
||||
gobject_class->set_property = gst_mio_video_device_set_property;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_CONTEXT,
|
||||
g_param_spec_pointer ("context", "CoreMedia Context",
|
||||
"CoreMedia context to use",
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_HANDLE,
|
||||
g_param_spec_int ("handle", "Handle",
|
||||
"MIO handle of this video capture device",
|
||||
G_MININT, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_UID,
|
||||
g_param_spec_string ("uid", "Unique ID",
|
||||
"Unique ID of this video capture device", NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_NAME,
|
||||
g_param_spec_string ("name", "Device Name",
|
||||
"Name of this video capture device", NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_TRANSPORT,
|
||||
g_param_spec_uint ("transport", "Transport",
|
||||
"Transport type of this video capture device",
|
||||
0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
GList *
|
||||
gst_mio_video_device_list_create (GstCoreMediaCtx * ctx)
|
||||
{
|
||||
GList *devices = NULL;
|
||||
TundraTargetSpec pspec = { 0, };
|
||||
GArray *handles;
|
||||
guint handle_idx;
|
||||
|
||||
pspec.name = kTundraSystemPropertyDevices;
|
||||
pspec.scope = kTundraScopeGlobal;
|
||||
handles = gst_mio_object_get_array (TUNDRA_SYSTEM_OBJECT_ID, &pspec,
|
||||
sizeof (TundraObjectID), ctx->mio);
|
||||
if (handles == NULL)
|
||||
goto beach;
|
||||
|
||||
for (handle_idx = 0; handle_idx != handles->len; handle_idx++) {
|
||||
TundraObjectID handle;
|
||||
GstMIOVideoDevice *device;
|
||||
|
||||
handle = g_array_index (handles, TundraObjectID, handle_idx);
|
||||
device = g_object_new (GST_TYPE_MIO_VIDEO_DEVICE,
|
||||
"context", ctx, "handle", handle, NULL);
|
||||
|
||||
/* TODO: Skip screen input devices for now */
|
||||
if (gst_mio_video_device_get_transport_type (device) !=
|
||||
kTundraDeviceTransportScreen) {
|
||||
devices = g_list_prepend (devices, device);
|
||||
} else {
|
||||
g_object_unref (device);
|
||||
}
|
||||
}
|
||||
|
||||
devices = g_list_sort (devices, (GCompareFunc) gst_mio_video_device_compare);
|
||||
|
||||
g_array_free (handles, TRUE);
|
||||
|
||||
beach:
|
||||
return devices;
|
||||
}
|
||||
|
||||
void
|
||||
gst_mio_video_device_list_destroy (GList * devices)
|
||||
{
|
||||
g_list_foreach (devices, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (devices);
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_mio_video_device_compare (GstMIOVideoDevice * a, GstMIOVideoDevice * b)
|
||||
{
|
||||
gint score_a, score_b;
|
||||
|
||||
score_a = gst_mio_video_device_calculate_score (a);
|
||||
score_b = gst_mio_video_device_calculate_score (b);
|
||||
|
||||
if (score_a > score_b)
|
||||
return -1;
|
||||
else if (score_a < score_b)
|
||||
return 1;
|
||||
|
||||
return g_ascii_strcasecmp (gst_mio_video_device_get_name (a),
|
||||
gst_mio_video_device_get_name (b));
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_mio_video_device_calculate_score (GstMIOVideoDevice * device)
|
||||
{
|
||||
switch (gst_mio_video_device_get_transport_type (device)) {
|
||||
case kTundraDeviceTransportScreen:
|
||||
return 0;
|
||||
case kTundraDeviceTransportBuiltin:
|
||||
return 1;
|
||||
case kTundraDeviceTransportUSB:
|
||||
return 2;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_MIO_VIDEO_DEVICE_H__
|
||||
#define __GST_MIO_VIDEO_DEVICE_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "coremediactx.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_MIO_VIDEO_DEVICE \
|
||||
(gst_mio_video_device_get_type ())
|
||||
#define GST_MIO_VIDEO_DEVICE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIO_VIDEO_DEVICE, GstMIOVideoDevice))
|
||||
#define GST_MIO_VIDEO_DEVICE_CAST(obj) \
|
||||
((GstMIOVideoDevice *) (obj))
|
||||
#define GST_MIO_VIDEO_DEVICE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIO_VIDEO_DEVICE, GstMIOVideoDeviceClass))
|
||||
#define GST_IS_MIO_VIDEO_DEVICE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIO_VIDEO_DEVICE))
|
||||
#define GST_IS_MIO_VIDEO_DEVICE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIO_VIDEO_DEVICE))
|
||||
|
||||
typedef struct _GstMIOVideoDevice GstMIOVideoDevice;
|
||||
typedef struct _GstMIOVideoDeviceClass GstMIOVideoDeviceClass;
|
||||
|
||||
struct _GstMIOVideoDevice
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GstCoreMediaCtx *ctx;
|
||||
TundraObjectID handle;
|
||||
|
||||
gchar *cached_uid;
|
||||
gchar *cached_name;
|
||||
TundraDeviceTransportType cached_transport;
|
||||
GstCaps *cached_caps;
|
||||
CMFormatDescriptionRef selected_format;
|
||||
gint selected_fps_n, selected_fps_d;
|
||||
};
|
||||
|
||||
struct _GstMIOVideoDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_mio_video_device_get_type (void);
|
||||
|
||||
TundraObjectID gst_mio_video_device_get_handle (GstMIOVideoDevice * self);
|
||||
const gchar * gst_mio_video_device_get_uid (GstMIOVideoDevice * self);
|
||||
const gchar * gst_mio_video_device_get_name (GstMIOVideoDevice * self);
|
||||
TundraDeviceTransportType gst_mio_video_device_get_transport_type (
|
||||
GstMIOVideoDevice * self);
|
||||
|
||||
gboolean gst_mio_video_device_open (GstMIOVideoDevice * self);
|
||||
void gst_mio_video_device_close (GstMIOVideoDevice * self);
|
||||
|
||||
GstCaps * gst_mio_video_device_get_available_caps (GstMIOVideoDevice * self);
|
||||
gboolean gst_mio_video_device_set_caps (GstMIOVideoDevice * self,
|
||||
GstCaps * caps);
|
||||
CMFormatDescriptionRef gst_mio_video_device_get_selected_format (
|
||||
GstMIOVideoDevice * self);
|
||||
GstClockTime gst_mio_video_device_get_duration (GstMIOVideoDevice * self);
|
||||
|
||||
void gst_mio_video_device_print_debug_info (GstMIOVideoDevice * self);
|
||||
|
||||
GList * gst_mio_video_device_list_create (GstCoreMediaCtx * ctx);
|
||||
void gst_mio_video_device_list_destroy (GList * devices);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MIO_VIDEO_DEVICE_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_MIO_VIDEO_SRC_H__
|
||||
#define __GST_MIO_VIDEO_SRC_H__
|
||||
|
||||
#include <gst/base/gstpushsrc.h>
|
||||
|
||||
#include "coremediactx.h"
|
||||
#include "miovideodevice.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_MIO_VIDEO_SRC \
|
||||
(gst_mio_video_src_get_type ())
|
||||
#define GST_MIO_VIDEO_SRC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIO_VIDEO_SRC, GstMIOVideoSrc))
|
||||
#define GST_MIO_VIDEO_SRC_CAST(obj) \
|
||||
((GstMIOVideoSrc *) (obj))
|
||||
#define GST_MIO_VIDEO_SRC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIO_VIDEO_SRC, GstMIOVideoSrcClass))
|
||||
#define GST_IS_MIO_VIDEO_SRC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIO_VIDEO_SRC))
|
||||
#define GST_IS_MIO_VIDEO_SRC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIO_VIDEO_SRC))
|
||||
|
||||
typedef struct _GstMIOVideoSrc GstMIOVideoSrc;
|
||||
typedef struct _GstMIOVideoSrcClass GstMIOVideoSrcClass;
|
||||
|
||||
struct _GstMIOVideoSrc
|
||||
{
|
||||
GstPushSrc push_src;
|
||||
|
||||
gint cv_ratio_n;
|
||||
gint cv_ratio_d;
|
||||
|
||||
gchar *device_uid;
|
||||
gchar *device_name;
|
||||
gint device_index;
|
||||
|
||||
GThread *dispatcher_thread;
|
||||
GMainLoop *dispatcher_loop;
|
||||
GMainContext *dispatcher_ctx;
|
||||
|
||||
GstCoreMediaCtx *ctx;
|
||||
GstMIOVideoDevice *device;
|
||||
|
||||
TundraGraph *graph;
|
||||
|
||||
volatile gboolean running;
|
||||
GQueue *queue;
|
||||
GMutex *qlock;
|
||||
GCond *qcond;
|
||||
guint64 prev_offset;
|
||||
CMFormatDescriptionRef prev_format;
|
||||
};
|
||||
|
||||
struct _GstMIOVideoSrcClass
|
||||
{
|
||||
GstPushSrcClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_mio_video_src_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MIO_VIDEO_SRC_H__ */
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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 "mtapi.h"
|
||||
|
||||
#include "dynapi-internal.h"
|
||||
|
||||
#define MT_FRAMEWORK_PATH "/System/Library/PrivateFrameworks/" \
|
||||
"MediaToolbox.framework/MediaToolbox"
|
||||
|
||||
G_DEFINE_TYPE (GstMTApi, gst_mt_api, GST_TYPE_DYN_API);
|
||||
|
||||
static void
|
||||
gst_mt_api_init (GstMTApi * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mt_api_class_init (GstMTApiClass * klass)
|
||||
{
|
||||
}
|
||||
|
||||
#define SYM_SPEC(name) GST_DYN_SYM_SPEC (GstMTApi, name)
|
||||
|
||||
GstMTApi *
|
||||
gst_mt_api_obtain (GError ** error)
|
||||
{
|
||||
static const GstDynSymSpec symbols[] = {
|
||||
SYM_SPEC (FigCaptureDeviceGetFigBaseObject),
|
||||
SYM_SPEC (FigCaptureStreamGetFigBaseObject),
|
||||
|
||||
SYM_SPEC (kFigCaptureDeviceProperty_Clock),
|
||||
SYM_SPEC (kFigCaptureDeviceProperty_StreamArray),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AudioLevelArray),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AudioLevelMeteringEnable),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AudioLevelUnits),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AutoAENow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_AutoFocusNow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_BufferAllocator),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_BufferQueue),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_FixedFrameRate),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_FormatDescription),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_FormatIndex),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_FrameDuration),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_MaximumFrameRate),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_MinimumFrameRate),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_NeedSampleBufferDurations),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_StillImageBufferQueue),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_StillImageCaptureNow),
|
||||
SYM_SPEC (kFigCaptureStreamProperty_SupportedFormatsArray),
|
||||
SYM_SPEC (kFigSupportedFormat_AudioMaxSampleRate),
|
||||
SYM_SPEC (kFigSupportedFormat_AudioMinSampleRate),
|
||||
SYM_SPEC (kFigSupportedFormat_FormatDescription),
|
||||
SYM_SPEC (kFigSupportedFormat_VideoIsBinned),
|
||||
SYM_SPEC (kFigSupportedFormat_VideoMaxFrameRate),
|
||||
SYM_SPEC (kFigSupportedFormat_VideoMinFrameRate),
|
||||
SYM_SPEC (kFigSupportedFormat_VideoScaleFactor),
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
return _gst_dyn_api_new (gst_mt_api_get_type (), MT_FRAMEWORK_PATH, symbols,
|
||||
error);
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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_MT_API_H__
|
||||
#define __GST_MT_API_H__
|
||||
|
||||
#include "cmapi.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstMTApi GstMTApi;
|
||||
typedef struct _GstMTApiClass GstMTApiClass;
|
||||
|
||||
typedef struct _FigCaptureDevice * FigCaptureDeviceRef;
|
||||
typedef struct _FigCaptureStream * FigCaptureStreamRef;
|
||||
typedef struct _FigCaptureDeviceIface FigCaptureDeviceIface;
|
||||
typedef struct _FigCaptureStreamIface FigCaptureStreamIface;
|
||||
|
||||
struct _FigCaptureDeviceIface
|
||||
{
|
||||
gsize unk;
|
||||
OSStatus (* Func1) (FigCaptureDeviceRef stream);
|
||||
};
|
||||
|
||||
struct _FigCaptureStreamIface
|
||||
{
|
||||
gsize unk;
|
||||
OSStatus (* Start) (FigCaptureStreamRef stream);
|
||||
OSStatus (* Stop) (FigCaptureStreamRef stream);
|
||||
};
|
||||
|
||||
struct _GstMTApi
|
||||
{
|
||||
GstDynApi parent;
|
||||
|
||||
FigBaseObjectRef (* FigCaptureDeviceGetFigBaseObject)
|
||||
(FigCaptureDeviceRef device);
|
||||
FigBaseObjectRef (* FigCaptureStreamGetFigBaseObject)
|
||||
(FigCaptureStreamRef stream);
|
||||
|
||||
CFStringRef * kFigCaptureDeviceProperty_Clock;
|
||||
CFStringRef * kFigCaptureDeviceProperty_StreamArray;
|
||||
CFStringRef * kFigCaptureStreamProperty_AudioLevelArray;
|
||||
CFStringRef * kFigCaptureStreamProperty_AudioLevelMeteringEnable;
|
||||
CFStringRef * kFigCaptureStreamProperty_AudioLevelUnits;
|
||||
CFStringRef * kFigCaptureStreamProperty_AutoAENow;
|
||||
CFStringRef * kFigCaptureStreamProperty_AutoFocusNow;
|
||||
CFStringRef * kFigCaptureStreamProperty_BufferAllocator;
|
||||
CFStringRef * kFigCaptureStreamProperty_BufferQueue;
|
||||
CFStringRef * kFigCaptureStreamProperty_FixedFrameRate;
|
||||
CFStringRef * kFigCaptureStreamProperty_FormatDescription;
|
||||
CFStringRef * kFigCaptureStreamProperty_FormatIndex;
|
||||
CFStringRef * kFigCaptureStreamProperty_FrameDuration;
|
||||
CFStringRef * kFigCaptureStreamProperty_MaximumFrameRate;
|
||||
CFStringRef * kFigCaptureStreamProperty_MinimumFrameRate;
|
||||
CFStringRef * kFigCaptureStreamProperty_NeedSampleBufferDurations;
|
||||
CFStringRef * kFigCaptureStreamProperty_StillImageBufferQueue;
|
||||
CFStringRef * kFigCaptureStreamProperty_StillImageCaptureNow;
|
||||
CFStringRef * kFigCaptureStreamProperty_SupportedFormatsArray;
|
||||
CFStringRef * kFigSupportedFormat_AudioMaxSampleRate;
|
||||
CFStringRef * kFigSupportedFormat_AudioMinSampleRate;
|
||||
CFStringRef * kFigSupportedFormat_FormatDescription;
|
||||
CFStringRef * kFigSupportedFormat_VideoIsBinned;
|
||||
CFStringRef * kFigSupportedFormat_VideoMaxFrameRate;
|
||||
CFStringRef * kFigSupportedFormat_VideoMinFrameRate;
|
||||
CFStringRef * kFigSupportedFormat_VideoScaleFactor;
|
||||
};
|
||||
|
||||
struct _GstMTApiClass
|
||||
{
|
||||
GstDynApiClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_mt_api_get_type (void);
|
||||
|
||||
GstMTApi * gst_mt_api_obtain (GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2010 Ole André Vadla Ravnås <oleavr@soundrop.com>
|
||||
*
|
||||
* 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
|
||||
|
||||
#ifdef HAVE_IOS
|
||||
#include "celvideosrc.h"
|
||||
#else
|
||||
#include "miovideosrc.h"
|
||||
#include <Foundation/Foundation.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_IOS
|
||||
static void
|
||||
enable_mt_mode (void)
|
||||
{
|
||||
NSThread * th = [[NSThread alloc] init];
|
||||
[th start];
|
||||
[th release];
|
||||
g_assert ([NSThread isMultiThreaded]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
|
||||
#ifdef HAVE_IOS
|
||||
#if 0
|
||||
res &= gst_element_register (plugin, "celvideosrc", GST_RANK_NONE,
|
||||
GST_TYPE_CEL_VIDEO_SRC);
|
||||
#endif
|
||||
#else
|
||||
enable_mt_mode ();
|
||||
|
||||
#if 0
|
||||
res &= gst_element_register (plugin, "miovideosrc", GST_RANK_NONE,
|
||||
GST_TYPE_MIO_VIDEO_SRC);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
applemedia_nonpublic,
|
||||
"Elements for capture and codec access on Apple OS X and iOS using private Frameworks",
|
||||
plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
|
Loading…
Reference in a new issue