mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
applemedia: don't use the dynamic API for public frameworks
Public frameworks don't need to build the API dynamically, we instead use the framework directly. The exception is for VideoToolbox which went public in the 10.8 SDK, but it's still private in older version of the SDK and iOS. This allow building the plugin against SDK's where it's not a public framework.
This commit is contained in:
parent
57b97beb6d
commit
97bb1edf6c
14 changed files with 77 additions and 653 deletions
|
@ -7,8 +7,6 @@ libgstapplemedia_la_SOURCES = \
|
||||||
corevideobuffer.c \
|
corevideobuffer.c \
|
||||||
coremediabuffer.c \
|
coremediabuffer.c \
|
||||||
coremediactx.c \
|
coremediactx.c \
|
||||||
cvapi.c \
|
|
||||||
cmapi.c \
|
|
||||||
vtapi.c \
|
vtapi.c \
|
||||||
dynapi.c
|
dynapi.c
|
||||||
|
|
||||||
|
@ -38,6 +36,7 @@ libgstapplemedia_la_LDFLAGS = \
|
||||||
$(GST_BASE_LDFLAGS) \
|
$(GST_BASE_LDFLAGS) \
|
||||||
$(GST_PLUGINS_BASE_LDFLAGS) \
|
$(GST_PLUGINS_BASE_LDFLAGS) \
|
||||||
-Wl,-framework -Wl,CoreFoundation \
|
-Wl,-framework -Wl,CoreFoundation \
|
||||||
|
-Wl,-framework -Wl,CoreMedia \
|
||||||
-Wl,-framework -Wl,CoreVideo
|
-Wl,-framework -Wl,CoreVideo
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
|
@ -52,8 +51,6 @@ noinst_HEADERS = \
|
||||||
corevideobuffer.h \
|
corevideobuffer.h \
|
||||||
coremediabuffer.h \
|
coremediabuffer.h \
|
||||||
coremediactx.h \
|
coremediactx.h \
|
||||||
cvapi.h \
|
|
||||||
cmapi.h \
|
|
||||||
vtapi.h \
|
vtapi.h \
|
||||||
dynapi.h \
|
dynapi.h \
|
||||||
dynapi-internal.h
|
dynapi-internal.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
|
|
|
@ -23,12 +23,10 @@ static void
|
||||||
gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf)
|
gst_core_media_meta_free (GstCoreMediaMeta * meta, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
if (meta->image_buf != NULL) {
|
if (meta->image_buf != NULL) {
|
||||||
GstCVApi *cv = meta->ctx->cv;
|
CVPixelBufferUnlockBaseAddress (meta->image_buf,
|
||||||
cv->CVPixelBufferUnlockBaseAddress (meta->image_buf,
|
|
||||||
kCVPixelBufferLock_ReadOnly);
|
kCVPixelBufferLock_ReadOnly);
|
||||||
}
|
}
|
||||||
meta->ctx->cm->FigSampleBufferRelease (meta->sample_buf);
|
CVBufferRelease ((CVBufferRef)meta->sample_buf);
|
||||||
g_object_unref (meta->ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
|
@ -61,53 +59,51 @@ gst_core_media_meta_get_info (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
GstBuffer *
|
GstBuffer *
|
||||||
gst_core_media_buffer_new (GstCoreMediaCtx * ctx, CMSampleBufferRef sample_buf)
|
gst_core_media_buffer_new (CMSampleBufferRef sample_buf)
|
||||||
{
|
{
|
||||||
GstCVApi *cv = ctx->cv;
|
|
||||||
GstCMApi *cm = ctx->cm;
|
|
||||||
CVImageBufferRef image_buf;
|
CVImageBufferRef image_buf;
|
||||||
CVPixelBufferRef pixel_buf;
|
CVPixelBufferRef pixel_buf;
|
||||||
CMBlockBufferRef block_buf;
|
CMBlockBufferRef block_buf;
|
||||||
Byte *data = NULL;
|
gchar *data = NULL;
|
||||||
UInt32 size;
|
UInt32 size;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstCoreMediaMeta *meta;
|
GstCoreMediaMeta *meta;
|
||||||
|
|
||||||
image_buf = cm->CMSampleBufferGetImageBuffer (sample_buf);
|
image_buf = CMSampleBufferGetImageBuffer (sample_buf);
|
||||||
pixel_buf = NULL;
|
pixel_buf = NULL;
|
||||||
block_buf = cm->CMSampleBufferGetDataBuffer (sample_buf);
|
block_buf = CMSampleBufferGetDataBuffer (sample_buf);
|
||||||
|
|
||||||
if (image_buf != NULL &&
|
if (image_buf != NULL &&
|
||||||
CFGetTypeID (image_buf) == cv->CVPixelBufferGetTypeID ()) {
|
CFGetTypeID (image_buf) == CVPixelBufferGetTypeID ()) {
|
||||||
pixel_buf = (CVPixelBufferRef) image_buf;
|
pixel_buf = (CVPixelBufferRef) image_buf;
|
||||||
|
|
||||||
if (cv->CVPixelBufferLockBaseAddress (pixel_buf,
|
if (CVPixelBufferLockBaseAddress (pixel_buf,
|
||||||
kCVPixelBufferLock_ReadOnly) != kCVReturnSuccess) {
|
kCVPixelBufferLock_ReadOnly) != kCVReturnSuccess) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv->CVPixelBufferIsPlanar (pixel_buf)) {
|
if (CVPixelBufferIsPlanar (pixel_buf)) {
|
||||||
gint plane_count, plane_idx;
|
gint plane_count, plane_idx;
|
||||||
|
|
||||||
data = cv->CVPixelBufferGetBaseAddressOfPlane (pixel_buf, 0);
|
data = CVPixelBufferGetBaseAddressOfPlane (pixel_buf, 0);
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
plane_count = cv->CVPixelBufferGetPlaneCount (pixel_buf);
|
plane_count = CVPixelBufferGetPlaneCount (pixel_buf);
|
||||||
for (plane_idx = 0; plane_idx != plane_count; plane_idx++) {
|
for (plane_idx = 0; plane_idx != plane_count; plane_idx++) {
|
||||||
size += cv->CVPixelBufferGetBytesPerRowOfPlane (pixel_buf, plane_idx) *
|
size += CVPixelBufferGetBytesPerRowOfPlane (pixel_buf, plane_idx) *
|
||||||
cv->CVPixelBufferGetHeightOfPlane (pixel_buf, plane_idx);
|
CVPixelBufferGetHeightOfPlane (pixel_buf, plane_idx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data = cv->CVPixelBufferGetBaseAddress (pixel_buf);
|
data = CVPixelBufferGetBaseAddress (pixel_buf);
|
||||||
size = cv->CVPixelBufferGetBytesPerRow (pixel_buf) *
|
size = CVPixelBufferGetBytesPerRow (pixel_buf) *
|
||||||
cv->CVPixelBufferGetHeight (pixel_buf);
|
CVPixelBufferGetHeight (pixel_buf);
|
||||||
}
|
}
|
||||||
} else if (block_buf != NULL) {
|
} else if (block_buf != NULL) {
|
||||||
status = cm->CMBlockBufferGetDataPointer (block_buf, 0, 0, 0, &data);
|
status = CMBlockBufferGetDataPointer (block_buf, 0, 0, 0, &data);
|
||||||
if (status != noErr)
|
if (status != noErr)
|
||||||
goto error;
|
goto error;
|
||||||
size = cm->CMBlockBufferGetDataLength (block_buf);
|
size = CMBlockBufferGetDataLength (block_buf);
|
||||||
} else {
|
} else {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -116,8 +112,8 @@ gst_core_media_buffer_new (GstCoreMediaCtx * ctx, CMSampleBufferRef sample_buf)
|
||||||
|
|
||||||
meta = (GstCoreMediaMeta *) gst_buffer_add_meta (buf,
|
meta = (GstCoreMediaMeta *) gst_buffer_add_meta (buf,
|
||||||
gst_core_media_meta_get_info (), NULL);
|
gst_core_media_meta_get_info (), NULL);
|
||||||
meta->ctx = g_object_ref (ctx);
|
CVBufferRetain ((CVBufferRef)sample_buf);
|
||||||
meta->sample_buf = cm->FigSampleBufferRetain (sample_buf);
|
meta->sample_buf = sample_buf;
|
||||||
meta->image_buf = image_buf;
|
meta->image_buf = image_buf;
|
||||||
meta->pixel_buf = pixel_buf;
|
meta->pixel_buf = pixel_buf;
|
||||||
meta->block_buf = block_buf;
|
meta->block_buf = block_buf;
|
||||||
|
@ -139,5 +135,5 @@ gst_core_media_buffer_get_pixel_buffer (GstBuffer * buf)
|
||||||
GST_CORE_MEDIA_META_API_TYPE);
|
GST_CORE_MEDIA_META_API_TYPE);
|
||||||
g_return_val_if_fail (meta != NULL, NULL);
|
g_return_val_if_fail (meta != NULL, NULL);
|
||||||
|
|
||||||
return meta->ctx->cv->CVPixelBufferRetain (meta->pixel_buf);
|
return CVPixelBufferRetain (meta->pixel_buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#include "coremediactx.h"
|
#include "CoreMedia/CoreMedia.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ typedef struct _GstCoreMediaMeta
|
||||||
{
|
{
|
||||||
GstMeta meta;
|
GstMeta meta;
|
||||||
|
|
||||||
GstCoreMediaCtx * ctx;
|
|
||||||
CMSampleBufferRef sample_buf;
|
CMSampleBufferRef sample_buf;
|
||||||
CVImageBufferRef image_buf;
|
CVImageBufferRef image_buf;
|
||||||
CVPixelBufferRef pixel_buf;
|
CVPixelBufferRef pixel_buf;
|
||||||
|
@ -42,8 +41,7 @@ typedef struct _GstCoreMediaMeta
|
||||||
} GstCoreMediaMeta;
|
} GstCoreMediaMeta;
|
||||||
|
|
||||||
|
|
||||||
GstBuffer * gst_core_media_buffer_new (GstCoreMediaCtx * ctx,
|
GstBuffer * gst_core_media_buffer_new (CMSampleBufferRef sample_buf);
|
||||||
CMSampleBufferRef sample_buf);
|
|
||||||
CVPixelBufferRef gst_core_media_buffer_get_pixel_buffer
|
CVPixelBufferRef gst_core_media_buffer_get_pixel_buffer
|
||||||
(GstBuffer * buf);
|
(GstBuffer * buf);
|
||||||
GType gst_core_media_meta_api_get_type (void);
|
GType gst_core_media_meta_api_get_type (void);
|
||||||
|
|
|
@ -41,8 +41,6 @@ struct _GstApiProvider
|
||||||
G_STRUCT_OFFSET (GstCoreMediaCtx, a_n) }
|
G_STRUCT_OFFSET (GstCoreMediaCtx, a_n) }
|
||||||
|
|
||||||
static const GstApiProvider api_provider[] = {
|
static const GstApiProvider api_provider[] = {
|
||||||
API_PROVIDER (CORE_VIDEO, cv),
|
|
||||||
API_PROVIDER (CORE_MEDIA, cm),
|
|
||||||
API_PROVIDER (VIDEO_TOOLBOX, vt),
|
API_PROVIDER (VIDEO_TOOLBOX, vt),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#ifndef __GST_CORE_MEDIA_CTX_H__
|
#ifndef __GST_CORE_MEDIA_CTX_H__
|
||||||
#define __GST_CORE_MEDIA_CTX_H__
|
#define __GST_CORE_MEDIA_CTX_H__
|
||||||
|
|
||||||
#include "cvapi.h"
|
|
||||||
#include "cmapi.h"
|
|
||||||
#include "vtapi.h"
|
#include "vtapi.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
@ -51,8 +49,6 @@ struct _GstCoreMediaCtx
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
/* Common */
|
/* Common */
|
||||||
GstCVApi *cv;
|
|
||||||
GstCMApi *cm;
|
|
||||||
GstVTApi *vt;
|
GstVTApi *vt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,9 +59,7 @@ struct _GstCoreMediaCtxClass
|
||||||
|
|
||||||
enum _GstCoreMediaApi
|
enum _GstCoreMediaApi
|
||||||
{
|
{
|
||||||
GST_API_CORE_VIDEO = (1 << 0),
|
GST_API_VIDEO_TOOLBOX = (1 << 0),
|
||||||
GST_API_CORE_MEDIA = (1 << 1),
|
|
||||||
GST_API_VIDEO_TOOLBOX = (1 << 2),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_core_media_ctx_get_type (void);
|
GType gst_core_media_ctx_get_type (void);
|
||||||
|
|
|
@ -22,15 +22,12 @@
|
||||||
static void
|
static void
|
||||||
gst_core_video_meta_free (GstCoreVideoMeta * meta, GstBuffer * buf)
|
gst_core_video_meta_free (GstCoreVideoMeta * meta, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstCVApi *cv = meta->ctx->cv;
|
|
||||||
|
|
||||||
if (meta->pixbuf != NULL) {
|
if (meta->pixbuf != NULL) {
|
||||||
cv->CVPixelBufferUnlockBaseAddress (meta->pixbuf,
|
CVPixelBufferUnlockBaseAddress (meta->pixbuf,
|
||||||
kCVPixelBufferLock_ReadOnly);
|
kCVPixelBufferLock_ReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
cv->CVBufferRelease (meta->cvbuf);
|
CVBufferRelease (meta->cvbuf);
|
||||||
g_object_unref (meta->ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
|
@ -63,10 +60,9 @@ gst_core_video_meta_get_info (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
GstBuffer *
|
GstBuffer *
|
||||||
gst_core_video_buffer_new (GstCoreMediaCtx * ctx, CVBufferRef cvbuf,
|
gst_core_video_buffer_new (CVBufferRef cvbuf,
|
||||||
GstVideoInfo * vinfo)
|
GstVideoInfo * vinfo)
|
||||||
{
|
{
|
||||||
GstCVApi *cv = ctx->cv;
|
|
||||||
void *data;
|
void *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
CVPixelBufferRef pixbuf = NULL;
|
CVPixelBufferRef pixbuf = NULL;
|
||||||
|
@ -76,13 +72,13 @@ gst_core_video_buffer_new (GstCoreMediaCtx * ctx, CVBufferRef cvbuf,
|
||||||
gsize offset[GST_VIDEO_MAX_PLANES];
|
gsize offset[GST_VIDEO_MAX_PLANES];
|
||||||
gint stride[GST_VIDEO_MAX_PLANES];
|
gint stride[GST_VIDEO_MAX_PLANES];
|
||||||
|
|
||||||
if (CFGetTypeID (cvbuf) != cv->CVPixelBufferGetTypeID ())
|
if (CFGetTypeID (cvbuf) != CVPixelBufferGetTypeID ())
|
||||||
/* TODO: Do we need to handle other buffer types? */
|
/* TODO: Do we need to handle other buffer types? */
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
pixbuf = (CVPixelBufferRef) cvbuf;
|
pixbuf = (CVPixelBufferRef) cvbuf;
|
||||||
|
|
||||||
if (cv->CVPixelBufferLockBaseAddress (pixbuf,
|
if (CVPixelBufferLockBaseAddress (pixbuf,
|
||||||
kCVPixelBufferLock_ReadOnly) != kCVReturnSuccess) {
|
kCVPixelBufferLock_ReadOnly) != kCVReturnSuccess) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -92,22 +88,21 @@ gst_core_video_buffer_new (GstCoreMediaCtx * ctx, CVBufferRef cvbuf,
|
||||||
/* add the corevideo meta to free the underlying corevideo buffer */
|
/* add the corevideo meta to free the underlying corevideo buffer */
|
||||||
meta = (GstCoreVideoMeta *) gst_buffer_add_meta (buf,
|
meta = (GstCoreVideoMeta *) gst_buffer_add_meta (buf,
|
||||||
gst_core_video_meta_get_info (), NULL);
|
gst_core_video_meta_get_info (), NULL);
|
||||||
meta->ctx = g_object_ref (ctx);
|
meta->cvbuf = CVBufferRetain (cvbuf);
|
||||||
meta->cvbuf = cv->CVBufferRetain (cvbuf);
|
|
||||||
meta->pixbuf = pixbuf;
|
meta->pixbuf = pixbuf;
|
||||||
|
|
||||||
/* set stride, offset and size */
|
/* set stride, offset and size */
|
||||||
memset (&offset, 0, sizeof (offset));
|
memset (&offset, 0, sizeof (offset));
|
||||||
memset (&stride, 0, sizeof (stride));
|
memset (&stride, 0, sizeof (stride));
|
||||||
|
|
||||||
data = cv->CVPixelBufferGetBaseAddress (pixbuf);
|
data = CVPixelBufferGetBaseAddress (pixbuf);
|
||||||
height = cv->CVPixelBufferGetHeight (pixbuf);
|
height = CVPixelBufferGetHeight (pixbuf);
|
||||||
if (cv->CVPixelBufferIsPlanar (pixbuf)) {
|
if (CVPixelBufferIsPlanar (pixbuf)) {
|
||||||
GstVideoInfo tmp_vinfo;
|
GstVideoInfo tmp_vinfo;
|
||||||
|
|
||||||
n_planes = cv->CVPixelBufferGetPlaneCount (pixbuf);
|
n_planes = CVPixelBufferGetPlaneCount (pixbuf);
|
||||||
for (i = 0; i < n_planes; ++i)
|
for (i = 0; i < n_planes; ++i)
|
||||||
stride[i] = cv->CVPixelBufferGetBytesPerRowOfPlane (pixbuf, i);
|
stride[i] = CVPixelBufferGetBytesPerRowOfPlane (pixbuf, i);
|
||||||
|
|
||||||
/* FIXME: don't hardcode NV12 */
|
/* FIXME: don't hardcode NV12 */
|
||||||
gst_video_info_init (&tmp_vinfo);
|
gst_video_info_init (&tmp_vinfo);
|
||||||
|
@ -117,7 +112,7 @@ gst_core_video_buffer_new (GstCoreMediaCtx * ctx, CVBufferRef cvbuf,
|
||||||
size = tmp_vinfo.size;
|
size = tmp_vinfo.size;
|
||||||
} else {
|
} else {
|
||||||
n_planes = 1;
|
n_planes = 1;
|
||||||
size = cv->CVPixelBufferGetBytesPerRow (pixbuf) * height;
|
size = CVPixelBufferGetBytesPerRow (pixbuf) * height;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_append_memory (buf,
|
gst_buffer_append_memory (buf,
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/video/gstvideometa.h>
|
#include <gst/video/gstvideometa.h>
|
||||||
|
|
||||||
#include "coremediactx.h"
|
#include "CoreVideo/CoreVideo.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -36,13 +36,11 @@ typedef struct _GstCoreVideoMeta
|
||||||
{
|
{
|
||||||
GstMeta meta;
|
GstMeta meta;
|
||||||
|
|
||||||
GstCoreMediaCtx *ctx;
|
|
||||||
CVBufferRef cvbuf;
|
CVBufferRef cvbuf;
|
||||||
CVPixelBufferRef pixbuf;
|
CVPixelBufferRef pixbuf;
|
||||||
} GstCoreVideoMeta;
|
} GstCoreVideoMeta;
|
||||||
|
|
||||||
GstBuffer * gst_core_video_buffer_new (GstCoreMediaCtx * ctx,
|
GstBuffer * gst_core_video_buffer_new (CVBufferRef cvbuf,
|
||||||
CVBufferRef cvbuf,
|
|
||||||
GstVideoInfo *info);
|
GstVideoInfo *info);
|
||||||
GType gst_core_video_meta_api_get_type (void);
|
GType gst_core_video_meta_api_get_type (void);
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -20,7 +20,8 @@
|
||||||
#ifndef __GST_VT_API_H__
|
#ifndef __GST_VT_API_H__
|
||||||
#define __GST_VT_API_H__
|
#define __GST_VT_API_H__
|
||||||
|
|
||||||
#include "cmapi.h"
|
#include "dynapi.h"
|
||||||
|
#include "CoreMedia/CoreMedia.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,11 @@ static gboolean gst_vtdec_sink_event (GstPad * pad, GstObject * parent,
|
||||||
static CMSampleBufferRef gst_vtdec_sample_buffer_from (GstVTDec * self,
|
static CMSampleBufferRef gst_vtdec_sample_buffer_from (GstVTDec * self,
|
||||||
GstBuffer * buf);
|
GstBuffer * buf);
|
||||||
|
|
||||||
|
extern OSStatus FigVideoFormatDescriptionCreateWithSampleDescriptionExtensionAtom
|
||||||
|
(CFAllocatorRef allocator, UInt32 formatId, UInt32 width, UInt32 height,
|
||||||
|
UInt32 atomId, const UInt8 * data, CFIndex len, void *unk1,
|
||||||
|
CMFormatDescriptionRef * formatDesc);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vtdec_base_init (GstVTDecClass * klass)
|
gst_vtdec_base_init (GstVTDecClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -143,8 +148,7 @@ gst_vtdec_change_state (GstElement * element, GstStateChange transition)
|
||||||
GstStateChangeReturn ret;
|
GstStateChangeReturn ret;
|
||||||
|
|
||||||
if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
|
if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
|
||||||
self->ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
|
self->ctx = gst_core_media_ctx_new (GST_API_VIDEO_TOOLBOX, &error);
|
||||||
| GST_API_VIDEO_TOOLBOX, &error);
|
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
goto api_error;
|
goto api_error;
|
||||||
|
|
||||||
|
@ -156,7 +160,7 @@ gst_vtdec_change_state (GstElement * element, GstStateChange transition)
|
||||||
if (transition == GST_STATE_CHANGE_READY_TO_NULL) {
|
if (transition == GST_STATE_CHANGE_READY_TO_NULL) {
|
||||||
gst_vtdec_destroy_session (self, &self->session);
|
gst_vtdec_destroy_session (self, &self->session);
|
||||||
|
|
||||||
self->ctx->cm->FigFormatDescriptionRelease (self->fmt_desc);
|
CFRelease (self->fmt_desc);
|
||||||
self->fmt_desc = NULL;
|
self->fmt_desc = NULL;
|
||||||
|
|
||||||
gst_video_info_init (&self->vinfo);
|
gst_video_info_init (&self->vinfo);
|
||||||
|
@ -261,7 +265,9 @@ gst_vtdec_sink_setcaps (GstVTDec * self, GstCaps * caps)
|
||||||
|
|
||||||
if (fmt_desc != NULL) {
|
if (fmt_desc != NULL) {
|
||||||
gst_vtdec_destroy_session (self, &self->session);
|
gst_vtdec_destroy_session (self, &self->session);
|
||||||
self->ctx->cm->FigFormatDescriptionRelease (self->fmt_desc);
|
if (self->fmt_desc != NULL) {
|
||||||
|
CFRelease (self->fmt_desc);
|
||||||
|
}
|
||||||
|
|
||||||
self->fmt_desc = fmt_desc;
|
self->fmt_desc = fmt_desc;
|
||||||
self->session = gst_vtdec_create_session (self, fmt_desc);
|
self->session = gst_vtdec_create_session (self, fmt_desc);
|
||||||
|
@ -339,7 +345,7 @@ gst_vtdec_create_format_description (GstVTDec * self)
|
||||||
CMFormatDescriptionRef fmt_desc;
|
CMFormatDescriptionRef fmt_desc;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
|
||||||
status = self->ctx->cm->CMVideoFormatDescriptionCreate (NULL,
|
status = CMVideoFormatDescriptionCreate (NULL,
|
||||||
self->details->format_id, self->vinfo.width, self->vinfo.height,
|
self->details->format_id, self->vinfo.width, self->vinfo.height,
|
||||||
NULL, &fmt_desc);
|
NULL, &fmt_desc);
|
||||||
if (status == noErr)
|
if (status == noErr)
|
||||||
|
@ -359,7 +365,6 @@ gst_vtdec_create_format_description_from_codec_data (GstVTDec * self,
|
||||||
gst_buffer_map (codec_data, &map, GST_MAP_READ);
|
gst_buffer_map (codec_data, &map, GST_MAP_READ);
|
||||||
|
|
||||||
status =
|
status =
|
||||||
self->ctx->cm->
|
|
||||||
FigVideoFormatDescriptionCreateWithSampleDescriptionExtensionAtom (NULL,
|
FigVideoFormatDescriptionCreateWithSampleDescriptionExtensionAtom (NULL,
|
||||||
self->details->format_id, self->vinfo.width, self->vinfo.height, 'avcC',
|
self->details->format_id, self->vinfo.width, self->vinfo.height, 'avcC',
|
||||||
map.data, map.size, NULL, &fmt_desc);
|
map.data, map.size, NULL, &fmt_desc);
|
||||||
|
@ -376,21 +381,20 @@ static VTDecompressionSessionRef
|
||||||
gst_vtdec_create_session (GstVTDec * self, CMFormatDescriptionRef fmt_desc)
|
gst_vtdec_create_session (GstVTDec * self, CMFormatDescriptionRef fmt_desc)
|
||||||
{
|
{
|
||||||
VTDecompressionSessionRef session = NULL;
|
VTDecompressionSessionRef session = NULL;
|
||||||
GstCVApi *cv = self->ctx->cv;
|
|
||||||
CFMutableDictionaryRef pb_attrs;
|
CFMutableDictionaryRef pb_attrs;
|
||||||
VTDecompressionOutputCallback callback;
|
VTDecompressionOutputCallback callback;
|
||||||
VTStatus status;
|
VTStatus status;
|
||||||
|
|
||||||
pb_attrs = CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
pb_attrs = CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferPixelFormatTypeKey),
|
gst_vtutil_dict_set_i32 (pb_attrs, kCVPixelBufferPixelFormatTypeKey,
|
||||||
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange);
|
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange);
|
||||||
gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferWidthKey),
|
gst_vtutil_dict_set_i32 (pb_attrs, kCVPixelBufferWidthKey,
|
||||||
self->vinfo.width);
|
self->vinfo.width);
|
||||||
gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferHeightKey),
|
gst_vtutil_dict_set_i32 (pb_attrs, kCVPixelBufferHeightKey,
|
||||||
self->vinfo.height);
|
self->vinfo.height);
|
||||||
gst_vtutil_dict_set_i32 (pb_attrs,
|
gst_vtutil_dict_set_i32 (pb_attrs,
|
||||||
*(cv->kCVPixelBufferBytesPerRowAlignmentKey), 2 * self->vinfo.width);
|
kCVPixelBufferBytesPerRowAlignmentKey, 2 * self->vinfo.width);
|
||||||
|
|
||||||
callback.func = gst_vtdec_enqueue_frame;
|
callback.func = gst_vtdec_enqueue_frame;
|
||||||
callback.data = self;
|
callback.data = self;
|
||||||
|
@ -439,7 +443,7 @@ gst_vtdec_decode_buffer (GstVTDec * self, GstBuffer * buf)
|
||||||
"VTDecompressionSessionWaitForAsynchronousFrames returned %d", status);
|
"VTDecompressionSessionWaitForAsynchronousFrames returned %d", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->ctx->cm->FigSampleBufferRelease (sbuf);
|
CFRelease (sbuf);
|
||||||
self->cur_inbuf = NULL;
|
self->cur_inbuf = NULL;
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
|
@ -472,7 +476,7 @@ gst_vtdec_enqueue_frame (void *data, gsize unk1, VTStatus result, gsize unk2,
|
||||||
if (result != kVTSuccess)
|
if (result != kVTSuccess)
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
buf = gst_core_video_buffer_new (self->ctx, cvbuf, &self->vinfo);
|
buf = gst_core_video_buffer_new (cvbuf, &self->vinfo);
|
||||||
gst_buffer_copy_into (buf, self->cur_inbuf, GST_BUFFER_COPY_METADATA, 0, -1);
|
gst_buffer_copy_into (buf, self->cur_inbuf, GST_BUFFER_COPY_METADATA, 0, -1);
|
||||||
|
|
||||||
g_ptr_array_add (self->cur_outbufs, buf);
|
g_ptr_array_add (self->cur_outbufs, buf);
|
||||||
|
@ -484,7 +488,6 @@ beach:
|
||||||
static CMSampleBufferRef
|
static CMSampleBufferRef
|
||||||
gst_vtdec_sample_buffer_from (GstVTDec * self, GstBuffer * buf)
|
gst_vtdec_sample_buffer_from (GstVTDec * self, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstCMApi *cm = self->ctx->cm;
|
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
CMBlockBufferRef bbuf = NULL;
|
CMBlockBufferRef bbuf = NULL;
|
||||||
CMSampleBufferRef sbuf = NULL;
|
CMSampleBufferRef sbuf = NULL;
|
||||||
|
@ -494,7 +497,7 @@ gst_vtdec_sample_buffer_from (GstVTDec * self, GstBuffer * buf)
|
||||||
|
|
||||||
gst_buffer_map (buf, &map, GST_MAP_READ);
|
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||||
|
|
||||||
status = cm->CMBlockBufferCreateWithMemoryBlock (NULL,
|
status = CMBlockBufferCreateWithMemoryBlock (NULL,
|
||||||
map.data, (gint64) map.size, kCFAllocatorNull, NULL, 0, (gint64) map.size,
|
map.data, (gint64) map.size, kCFAllocatorNull, NULL, 0, (gint64) map.size,
|
||||||
FALSE, &bbuf);
|
FALSE, &bbuf);
|
||||||
|
|
||||||
|
@ -503,13 +506,13 @@ gst_vtdec_sample_buffer_from (GstVTDec * self, GstBuffer * buf)
|
||||||
if (status != noErr)
|
if (status != noErr)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
status = cm->CMSampleBufferCreate (NULL, bbuf, TRUE, 0, 0, self->fmt_desc,
|
status = CMSampleBufferCreate (NULL, bbuf, TRUE, 0, 0, self->fmt_desc,
|
||||||
1, 0, NULL, 0, NULL, &sbuf);
|
1, 0, NULL, 0, NULL, &sbuf);
|
||||||
if (status != noErr)
|
if (status != noErr)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
cm->FigBlockBufferRelease (bbuf);
|
CFRelease (bbuf);
|
||||||
return sbuf;
|
return sbuf;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
|
@ -295,8 +295,7 @@ gst_vtenc_change_state (GstElement * element, GstStateChange transition)
|
||||||
GstStateChangeReturn ret;
|
GstStateChangeReturn ret;
|
||||||
|
|
||||||
if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
|
if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
|
||||||
self->ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
|
self->ctx = gst_core_media_ctx_new (GST_API_VIDEO_TOOLBOX, &error);
|
||||||
| GST_API_VIDEO_TOOLBOX, &error);
|
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
goto api_error;
|
goto api_error;
|
||||||
|
|
||||||
|
@ -409,7 +408,6 @@ static gboolean
|
||||||
gst_vtenc_negotiate_downstream (GstVTEnc * self, CMSampleBufferRef sbuf)
|
gst_vtenc_negotiate_downstream (GstVTEnc * self, CMSampleBufferRef sbuf)
|
||||||
{
|
{
|
||||||
gboolean result;
|
gboolean result;
|
||||||
GstCMApi *cm = self->ctx->cm;
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
|
||||||
|
@ -437,9 +435,9 @@ gst_vtenc_negotiate_downstream (GstVTEnc * self, CMSampleBufferRef sbuf)
|
||||||
gsize codec_data_size;
|
gsize codec_data_size;
|
||||||
GstBuffer *codec_data_buf;
|
GstBuffer *codec_data_buf;
|
||||||
|
|
||||||
fmt = cm->CMSampleBufferGetFormatDescription (sbuf);
|
fmt = CMSampleBufferGetFormatDescription (sbuf);
|
||||||
atoms = cm->CMFormatDescriptionGetExtension (fmt,
|
atoms = CMFormatDescriptionGetExtension (fmt,
|
||||||
*(cm->kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms));
|
kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms);
|
||||||
avccKey = CFStringCreateWithCString (NULL, "avcC", kCFStringEncodingUTF8);
|
avccKey = CFStringCreateWithCString (NULL, "avcC", kCFStringEncodingUTF8);
|
||||||
avcc = CFDictionaryGetValue (atoms, avccKey);
|
avcc = CFDictionaryGetValue (atoms, avccKey);
|
||||||
CFRelease (avccKey);
|
CFRelease (avccKey);
|
||||||
|
@ -525,7 +523,6 @@ static VTCompressionSessionRef
|
||||||
gst_vtenc_create_session (GstVTEnc * self)
|
gst_vtenc_create_session (GstVTEnc * self)
|
||||||
{
|
{
|
||||||
VTCompressionSessionRef session = NULL;
|
VTCompressionSessionRef session = NULL;
|
||||||
GstCVApi *cv = self->ctx->cv;
|
|
||||||
GstVTApi *vt = self->ctx->vt;
|
GstVTApi *vt = self->ctx->vt;
|
||||||
CFMutableDictionaryRef pb_attrs;
|
CFMutableDictionaryRef pb_attrs;
|
||||||
VTCompressionOutputCallback callback;
|
VTCompressionOutputCallback callback;
|
||||||
|
@ -533,11 +530,11 @@ gst_vtenc_create_session (GstVTEnc * self)
|
||||||
|
|
||||||
pb_attrs = CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
pb_attrs = CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferPixelFormatTypeKey),
|
gst_vtutil_dict_set_i32 (pb_attrs, kCVPixelBufferPixelFormatTypeKey,
|
||||||
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange);
|
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange);
|
||||||
gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferWidthKey),
|
gst_vtutil_dict_set_i32 (pb_attrs, kCVPixelBufferWidthKey,
|
||||||
self->negotiated_width);
|
self->negotiated_width);
|
||||||
gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferHeightKey),
|
gst_vtutil_dict_set_i32 (pb_attrs, kCVPixelBufferHeightKey,
|
||||||
self->negotiated_height);
|
self->negotiated_height);
|
||||||
|
|
||||||
callback.func = gst_vtenc_enqueue_buffer;
|
callback.func = gst_vtenc_enqueue_buffer;
|
||||||
|
@ -753,7 +750,6 @@ gst_vtenc_session_configure_property_double (GstVTEnc * self,
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstCVApi *cv = self->ctx->cv;
|
|
||||||
GstVTApi *vt = self->ctx->vt;
|
GstVTApi *vt = self->ctx->vt;
|
||||||
CMTime ts, duration;
|
CMTime ts, duration;
|
||||||
GstCoreMediaMeta *meta;
|
GstCoreMediaMeta *meta;
|
||||||
|
@ -764,9 +760,9 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
||||||
|
|
||||||
self->cur_inbuf = buf;
|
self->cur_inbuf = buf;
|
||||||
|
|
||||||
ts = self->ctx->cm->CMTimeMake
|
ts = CMTimeMake
|
||||||
(GST_TIME_AS_MSECONDS (GST_BUFFER_TIMESTAMP (buf)), 1000);
|
(GST_TIME_AS_MSECONDS (GST_BUFFER_TIMESTAMP (buf)), 1000);
|
||||||
duration = self->ctx->cm->CMTimeMake
|
duration = CMTimeMake
|
||||||
(GST_TIME_AS_MSECONDS (GST_BUFFER_DURATION (buf)), 1000);
|
(GST_TIME_AS_MSECONDS (GST_BUFFER_DURATION (buf)), 1000);
|
||||||
|
|
||||||
meta = gst_buffer_get_core_media_meta (buf);
|
meta = gst_buffer_get_core_media_meta (buf);
|
||||||
|
@ -779,9 +775,9 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
||||||
CVReturn cv_ret;
|
CVReturn cv_ret;
|
||||||
|
|
||||||
frame = gst_vtenc_frame_new (buf);
|
frame = gst_vtenc_frame_new (buf);
|
||||||
cv_ret = cv->CVPixelBufferCreateWithBytes (NULL,
|
cv_ret = CVPixelBufferCreateWithBytes (NULL,
|
||||||
self->negotiated_width, self->negotiated_height,
|
self->negotiated_width, self->negotiated_height,
|
||||||
kCVPixelFormatType_422YpCbCr8Deprecated, frame->map.data,
|
kCVPixelFormatType_422YpCbCr8, frame->map.data,
|
||||||
self->negotiated_width * 2,
|
self->negotiated_width * 2,
|
||||||
(CVPixelBufferReleaseBytesCallback) gst_vtenc_frame_free, frame,
|
(CVPixelBufferReleaseBytesCallback) gst_vtenc_frame_free, frame,
|
||||||
NULL, &pbuf);
|
NULL, &pbuf);
|
||||||
|
@ -807,11 +803,11 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
self->ctx->vt->VTCompressionSessionCompleteFrames (self->session,
|
self->ctx->vt->VTCompressionSessionCompleteFrames (self->session,
|
||||||
*(self->ctx->cm->kCMTimeInvalid));
|
kCMTimeInvalid);
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (self);
|
GST_OBJECT_UNLOCK (self);
|
||||||
|
|
||||||
cv->CVPixelBufferRelease (pbuf);
|
CVPixelBufferRelease (pbuf);
|
||||||
self->cur_inbuf = NULL;
|
self->cur_inbuf = NULL;
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
|
@ -866,7 +862,7 @@ gst_vtenc_enqueue_buffer (void *data, int a2, int a3, int a4,
|
||||||
}
|
}
|
||||||
self->expect_keyframe = FALSE;
|
self->expect_keyframe = FALSE;
|
||||||
|
|
||||||
buf = gst_core_media_buffer_new (self->ctx, sbuf);
|
buf = gst_core_media_buffer_new (sbuf);
|
||||||
gst_buffer_copy_into (buf, self->cur_inbuf, GST_BUFFER_COPY_TIMESTAMPS,
|
gst_buffer_copy_into (buf, self->cur_inbuf, GST_BUFFER_COPY_TIMESTAMPS,
|
||||||
0, -1);
|
0, -1);
|
||||||
if (is_keyframe) {
|
if (is_keyframe) {
|
||||||
|
@ -889,14 +885,14 @@ gst_vtenc_buffer_is_keyframe (GstVTEnc * self, CMSampleBufferRef sbuf)
|
||||||
CFArrayRef attachments_for_sample;
|
CFArrayRef attachments_for_sample;
|
||||||
|
|
||||||
attachments_for_sample =
|
attachments_for_sample =
|
||||||
self->ctx->cm->CMSampleBufferGetSampleAttachmentsArray (sbuf, 0);
|
CMSampleBufferGetSampleAttachmentsArray (sbuf, 0);
|
||||||
if (attachments_for_sample != NULL) {
|
if (attachments_for_sample != NULL) {
|
||||||
CFDictionaryRef attachments;
|
CFDictionaryRef attachments;
|
||||||
CFBooleanRef depends_on_others;
|
CFBooleanRef depends_on_others;
|
||||||
|
|
||||||
attachments = CFArrayGetValueAtIndex (attachments_for_sample, 0);
|
attachments = CFArrayGetValueAtIndex (attachments_for_sample, 0);
|
||||||
depends_on_others = CFDictionaryGetValue (attachments,
|
depends_on_others = CFDictionaryGetValue (attachments,
|
||||||
*(self->ctx->cm->kCMSampleAttachmentKey_DependsOnOthers));
|
kCMSampleAttachmentKey_DependsOnOthers);
|
||||||
result = (depends_on_others == kCFBooleanFalse);
|
result = (depends_on_others == kCFBooleanFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue