mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-10 10:04:23 +00:00
vtenc: Port to the real VideoToolbox API instead of using our dlopen() wrapper
It's a public framework since a long time.
This commit is contained in:
parent
5dc2843c86
commit
f2eedb9cee
12 changed files with 65 additions and 1094 deletions
|
@ -5,22 +5,14 @@ libgstapplemedia_la_SOURCES = \
|
|||
vtutil.c \
|
||||
corevideobuffer.c \
|
||||
coremediabuffer.c \
|
||||
coremediactx.c \
|
||||
vtapi.c \
|
||||
atdec.c \
|
||||
dynapi.c
|
||||
atdec.c
|
||||
|
||||
libgstapplemedia_la_CPPFLAGS = \
|
||||
-Dgst_dyn_api_get_type=gst_dyn_api_priv_get_type \
|
||||
-Dgst_dyn_api_debug=gst_dyn_api_priv_debug \
|
||||
-D_gst_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
|
||||
-Dgst_core_video_buffer_get_type=gst_core_video_buffer_priv_get_type
|
||||
|
||||
libgstapplemedia_la_CFLAGS = \
|
||||
$(GST_CFLAGS) \
|
||||
|
@ -64,11 +56,7 @@ noinst_HEADERS = \
|
|||
vtutil.h \
|
||||
corevideobuffer.h \
|
||||
coremediabuffer.h \
|
||||
coremediactx.h \
|
||||
vtapi.h \
|
||||
atdec.h \
|
||||
dynapi.h \
|
||||
dynapi-internal.h \
|
||||
iosassetsrc.h \
|
||||
avfassetsrc.h
|
||||
|
||||
|
|
|
@ -1,127 +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 (VIDEO_TOOLBOX, vt),
|
||||
};
|
||||
|
||||
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,72 +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 "vtapi.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 */
|
||||
GstVTApi *vt;
|
||||
};
|
||||
|
||||
struct _GstCoreMediaCtxClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum _GstCoreMediaApi
|
||||
{
|
||||
GST_API_VIDEO_TOOLBOX = (1 << 0),
|
||||
};
|
||||
|
||||
GType gst_core_media_ctx_get_type (void);
|
||||
|
||||
GstCoreMediaCtx * gst_core_media_ctx_new (GstCoreMediaApi required_apis,
|
||||
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,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,100 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010, 2013 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 "vtapi.h"
|
||||
|
||||
#include "dynapi-internal.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#define VT_FRAMEWORK_PATH "/System/Library/Frameworks/" \
|
||||
"VideoToolbox.framework/VideoToolbox"
|
||||
#define VT_FRAMEWORK_PATH_OLD "/System/Library/PrivateFrameworks/" \
|
||||
"VideoToolbox.framework/VideoToolbox"
|
||||
|
||||
G_DEFINE_TYPE (GstVTApi, gst_vt_api, GST_TYPE_DYN_API);
|
||||
|
||||
static void
|
||||
gst_vt_api_init (GstVTApi * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vt_api_class_init (GstVTApiClass * klass)
|
||||
{
|
||||
}
|
||||
|
||||
#define SYM_SPEC(name) GST_DYN_SYM_SPEC (GstVTApi, name)
|
||||
|
||||
GstVTApi *
|
||||
gst_vt_api_obtain (GError ** error)
|
||||
{
|
||||
static const GstDynSymSpec symbols[] = {
|
||||
SYM_SPEC (VTCompressionSessionCompleteFrames),
|
||||
SYM_SPEC (VTCompressionSessionCopyProperty),
|
||||
SYM_SPEC (VTCompressionSessionCopySupportedPropertyDictionary),
|
||||
SYM_SPEC (VTCompressionSessionCreate),
|
||||
SYM_SPEC (VTCompressionSessionEncodeFrame),
|
||||
SYM_SPEC (VTCompressionSessionInvalidate),
|
||||
SYM_SPEC (VTCompressionSessionSetProperty),
|
||||
|
||||
SYM_SPEC (VTDecompressionSessionCreate),
|
||||
SYM_SPEC (VTDecompressionSessionDecodeFrame),
|
||||
SYM_SPEC (VTDecompressionSessionInvalidate),
|
||||
SYM_SPEC (VTDecompressionSessionWaitForAsynchronousFrames),
|
||||
SYM_SPEC (VTDecompressionSessionFinishDelayedFrames),
|
||||
|
||||
SYM_SPEC (kVTCompressionPropertyKey_AllowTemporalCompression),
|
||||
SYM_SPEC (kVTCompressionPropertyKey_AverageDataRate),
|
||||
SYM_SPEC (kVTCompressionPropertyKey_ExpectedFrameRate),
|
||||
SYM_SPEC (kVTCompressionPropertyKey_ExpectedDuration),
|
||||
SYM_SPEC (kVTCompressionPropertyKey_MaxKeyFrameInterval),
|
||||
SYM_SPEC (kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration),
|
||||
SYM_SPEC (kVTCompressionPropertyKey_ProfileLevel),
|
||||
SYM_SPEC (kVTCompressionPropertyKey_Usage),
|
||||
|
||||
SYM_SPEC (kVTEncodeFrameOptionKey_ForceKeyFrame),
|
||||
|
||||
SYM_SPEC (kVTProfileLevel_H264_Baseline_1_3),
|
||||
SYM_SPEC (kVTProfileLevel_H264_Baseline_3_0),
|
||||
SYM_SPEC (kVTProfileLevel_H264_Extended_5_0),
|
||||
SYM_SPEC (kVTProfileLevel_H264_High_5_0),
|
||||
SYM_SPEC (kVTProfileLevel_H264_Main_3_0),
|
||||
SYM_SPEC (kVTProfileLevel_H264_Main_3_1),
|
||||
SYM_SPEC (kVTProfileLevel_H264_Main_4_0),
|
||||
SYM_SPEC (kVTProfileLevel_H264_Main_4_1),
|
||||
SYM_SPEC (kVTProfileLevel_H264_Main_5_0),
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
GstVTApi *result;
|
||||
GModule *module;
|
||||
|
||||
module = g_module_open (VT_FRAMEWORK_PATH, 0);
|
||||
if (module != NULL) {
|
||||
result = _gst_dyn_api_new (gst_vt_api_get_type (), VT_FRAMEWORK_PATH,
|
||||
symbols, error);
|
||||
g_module_close (module);
|
||||
} else {
|
||||
result = _gst_dyn_api_new (gst_vt_api_get_type (), VT_FRAMEWORK_PATH_OLD,
|
||||
symbols, error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,165 +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_VT_API_H__
|
||||
#define __GST_VT_API_H__
|
||||
|
||||
#include "dynapi.h"
|
||||
#include "CoreMedia/CoreMedia.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVTApi GstVTApi;
|
||||
typedef struct _GstVTApiClass GstVTApiClass;
|
||||
|
||||
typedef enum _VTStatus VTStatus;
|
||||
typedef enum _VTDecodeFrameFlags VTDecodeFrameFlags;
|
||||
typedef enum _VTDecodeInfoFlags VTDecodeInfoFlags;
|
||||
|
||||
typedef guint32 VTFormatId;
|
||||
|
||||
typedef CFTypeRef VTCompressionSessionRef;
|
||||
typedef CFTypeRef VTDecompressionSessionRef;
|
||||
typedef struct _VTCompressionOutputCallback VTCompressionOutputCallback;
|
||||
typedef struct _VTDecompressionOutputCallback VTDecompressionOutputCallback;
|
||||
|
||||
typedef VTStatus (* VTCompressionOutputCallbackFunc) (void * data, int a2,
|
||||
int a3, int a4, CMSampleBufferRef sbuf, int a6, int a7);
|
||||
typedef void (* VTDecompressionOutputCallbackFunc) (void *data1, void *data2,
|
||||
VTStatus result, VTDecodeInfoFlags info, CVBufferRef cvbuf,
|
||||
CMTime pts, CMTime dts);
|
||||
|
||||
enum _VTStatus
|
||||
{
|
||||
kVTSuccess = 0
|
||||
};
|
||||
|
||||
enum _VTFormat
|
||||
{
|
||||
kVTFormatH264 = 'avc1',
|
||||
kVTFormatMPEG2 = 'mp2v',
|
||||
kVTFormatJPEG = 'jpeg'
|
||||
};
|
||||
|
||||
enum _VTDecodeFrameFlags
|
||||
{
|
||||
kVTDecodeFrame_EnableAsynchronousDecompression = 1<<0,
|
||||
kVTDecodeFrame_DoNotOutputFrame = 1<<1,
|
||||
/* low-power mode that can not decode faster than 1x realtime. */
|
||||
kVTDecodeFrame_1xRealTimePlayback = 1<<2,
|
||||
/* Output frame in PTS order.
|
||||
* Needs to call VTDecompressionSessionFinishDelayedFrames to dequeue */
|
||||
kVTDecodeFrame_EnableTemporalProcessing = 1<<3,
|
||||
};
|
||||
|
||||
enum _VTDecodeInfoFlags
|
||||
{
|
||||
kVTDecodeInfo_Asynchronous = 1UL << 0,
|
||||
kVTDecodeInfo_FrameDropped = 1UL << 1,
|
||||
};
|
||||
|
||||
struct _VTCompressionOutputCallback
|
||||
{
|
||||
VTCompressionOutputCallbackFunc func;
|
||||
void * data;
|
||||
};
|
||||
|
||||
struct _VTDecompressionOutputCallback
|
||||
{
|
||||
VTDecompressionOutputCallbackFunc func;
|
||||
void * data;
|
||||
};
|
||||
|
||||
struct _GstVTApi
|
||||
{
|
||||
GstDynApi parent;
|
||||
|
||||
VTStatus (* VTCompressionSessionCompleteFrames)
|
||||
(VTCompressionSessionRef session, CMTime completeUntilDisplayTimestamp);
|
||||
VTStatus (* VTCompressionSessionCopyProperty)
|
||||
(VTCompressionSessionRef session, CFTypeRef key, void* unk,
|
||||
CFTypeRef * value);
|
||||
VTStatus (* VTCompressionSessionCopySupportedPropertyDictionary)
|
||||
(VTCompressionSessionRef session, CFDictionaryRef * dict);
|
||||
VTStatus (* VTCompressionSessionCreate)
|
||||
(CFAllocatorRef allocator, gint width, gint height, VTFormatId formatId,
|
||||
gsize unk1, CFDictionaryRef sourcePixelBufferAttributes, gsize unk2,
|
||||
VTCompressionOutputCallback outputCallback,
|
||||
VTCompressionSessionRef * session);
|
||||
VTStatus (* VTCompressionSessionEncodeFrame)
|
||||
(VTCompressionSessionRef session, CVPixelBufferRef pixelBuffer,
|
||||
CMTime displayTimestamp, CMTime displayDuration,
|
||||
CFDictionaryRef frameOptions, void * sourceTrackingCallback,
|
||||
void * sourceFrameRefCon);
|
||||
void (* VTCompressionSessionInvalidate)
|
||||
(VTCompressionSessionRef session);
|
||||
VTStatus (* VTCompressionSessionSetProperty)
|
||||
(VTCompressionSessionRef session, CFStringRef propName,
|
||||
CFTypeRef propValue);
|
||||
|
||||
VTStatus (* VTDecompressionSessionCreate)
|
||||
(CFAllocatorRef allocator,
|
||||
CMFormatDescriptionRef videoFormatDescription,
|
||||
CFTypeRef sessionOptions,
|
||||
CFDictionaryRef destinationPixelBufferAttributes,
|
||||
VTDecompressionOutputCallback * outputCallback,
|
||||
VTDecompressionSessionRef * session);
|
||||
VTStatus (* VTDecompressionSessionDecodeFrame)
|
||||
(VTDecompressionSessionRef session, CMSampleBufferRef sbuf,
|
||||
VTDecodeFrameFlags decode_flags, void *src_buf,
|
||||
VTDecodeInfoFlags *info_flags);
|
||||
void (* VTDecompressionSessionInvalidate)
|
||||
(VTDecompressionSessionRef session);
|
||||
VTStatus (* VTDecompressionSessionWaitForAsynchronousFrames)
|
||||
(VTDecompressionSessionRef session);
|
||||
VTStatus (* VTDecompressionSessionFinishDelayedFrames)
|
||||
(VTDecompressionSessionRef session);
|
||||
|
||||
CFStringRef * kVTCompressionPropertyKey_AllowTemporalCompression;
|
||||
CFStringRef * kVTCompressionPropertyKey_AverageDataRate;
|
||||
CFStringRef * kVTCompressionPropertyKey_ExpectedFrameRate;
|
||||
CFStringRef * kVTCompressionPropertyKey_ExpectedDuration;
|
||||
CFStringRef * kVTCompressionPropertyKey_MaxKeyFrameInterval;
|
||||
CFStringRef * kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration;
|
||||
CFStringRef * kVTCompressionPropertyKey_ProfileLevel;
|
||||
CFStringRef * kVTCompressionPropertyKey_Usage;
|
||||
CFStringRef * kVTEncodeFrameOptionKey_ForceKeyFrame;
|
||||
CFStringRef * kVTProfileLevel_H264_Baseline_1_3;
|
||||
CFStringRef * kVTProfileLevel_H264_Baseline_3_0;
|
||||
CFStringRef * kVTProfileLevel_H264_Extended_5_0;
|
||||
CFStringRef * kVTProfileLevel_H264_High_5_0;
|
||||
CFStringRef * kVTProfileLevel_H264_Main_3_0;
|
||||
CFStringRef * kVTProfileLevel_H264_Main_3_1;
|
||||
CFStringRef * kVTProfileLevel_H264_Main_4_0;
|
||||
CFStringRef * kVTProfileLevel_H264_Main_4_1;
|
||||
CFStringRef * kVTProfileLevel_H264_Main_5_0;
|
||||
};
|
||||
|
||||
struct _GstVTApiClass
|
||||
{
|
||||
GstDynApiClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_vt_api_get_type (void);
|
||||
|
||||
GstVTApi * gst_vt_api_obtain (GError ** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -72,8 +72,6 @@ static void gst_vtenc_destroy_session (GstVTEnc * self,
|
|||
VTCompressionSessionRef * session);
|
||||
static void gst_vtenc_session_dump_properties (GstVTEnc * self,
|
||||
VTCompressionSessionRef session);
|
||||
static void gst_vtenc_session_configure_usage (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, gint usage);
|
||||
static void gst_vtenc_session_configure_expected_framerate (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, gdouble framerate);
|
||||
static void gst_vtenc_session_configure_expected_duration (GstVTEnc * self,
|
||||
|
@ -84,14 +82,16 @@ static void gst_vtenc_session_configure_max_keyframe_interval_duration
|
|||
(GstVTEnc * self, VTCompressionSessionRef session, gdouble duration);
|
||||
static void gst_vtenc_session_configure_bitrate (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, guint bitrate);
|
||||
static VTStatus gst_vtenc_session_configure_property_int (GstVTEnc * self,
|
||||
static OSStatus gst_vtenc_session_configure_property_int (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, CFStringRef name, gint value);
|
||||
static VTStatus gst_vtenc_session_configure_property_double (GstVTEnc * self,
|
||||
static OSStatus gst_vtenc_session_configure_property_double (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, CFStringRef name, gdouble value);
|
||||
|
||||
static GstFlowReturn gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf);
|
||||
static VTStatus gst_vtenc_enqueue_buffer (void *data, int a2, int a3, int a4,
|
||||
CMSampleBufferRef sbuf, int a6, int a7);
|
||||
static void gst_vtenc_enqueue_buffer (void *outputCallbackRefCon,
|
||||
void *sourceFrameRefCon,
|
||||
OSStatus status,
|
||||
VTEncodeInfoFlags infoFlags, CMSampleBufferRef sampleBuffer);
|
||||
static gboolean gst_vtenc_buffer_is_keyframe (GstVTEnc * self,
|
||||
CMSampleBufferRef sbuf);
|
||||
|
||||
|
@ -139,7 +139,7 @@ gst_vtenc_base_init (GstVTEncClass * klass)
|
|||
"height", GST_TYPE_INT_RANGE, min_height, max_height,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE,
|
||||
min_fps_n, min_fps_d, max_fps_n, max_fps_d, NULL);
|
||||
if (codec_details->format_id == kVTFormatH264) {
|
||||
if (codec_details->format_id == kCMVideoCodecType_H264) {
|
||||
gst_structure_set (gst_caps_get_structure (src_caps, 0),
|
||||
"stream-format", G_TYPE_STRING, "avc", NULL);
|
||||
}
|
||||
|
@ -164,11 +164,6 @@ gst_vtenc_class_init (GstVTEncClass * klass)
|
|||
|
||||
gstelement_class->change_state = gst_vtenc_change_state;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_USAGE,
|
||||
g_param_spec_int ("usage", "Usage",
|
||||
"Usage enumeration value",
|
||||
G_MININT, G_MAXINT, VTENC_DEFAULT_USAGE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class, PROP_BITRATE,
|
||||
g_param_spec_uint ("bitrate", "Bitrate",
|
||||
"Target video bitrate in kbps",
|
||||
|
@ -203,31 +198,6 @@ gst_vtenc_init (GstVTEnc * self)
|
|||
self->session = NULL;
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_vtenc_get_usage (GstVTEnc * self)
|
||||
{
|
||||
gint result;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
result = self->usage;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vtenc_set_usage (GstVTEnc * self, gint usage)
|
||||
{
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
self->usage = usage;
|
||||
|
||||
if (self->session != NULL)
|
||||
gst_vtenc_session_configure_usage (self, self->session, usage);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
}
|
||||
|
||||
static guint
|
||||
gst_vtenc_get_bitrate (GstVTEnc * self)
|
||||
{
|
||||
|
@ -260,9 +230,6 @@ gst_vtenc_get_property (GObject * obj, guint prop_id, GValue * value,
|
|||
GstVTEnc *self = GST_VTENC_CAST (obj);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_USAGE:
|
||||
g_value_set_int (value, gst_vtenc_get_usage (self));
|
||||
break;
|
||||
case PROP_BITRATE:
|
||||
g_value_set_uint (value, gst_vtenc_get_bitrate (self) * 8 / 1000);
|
||||
break;
|
||||
|
@ -279,9 +246,6 @@ gst_vtenc_set_property (GObject * obj, guint prop_id, const GValue * value,
|
|||
GstVTEnc *self = GST_VTENC_CAST (obj);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_USAGE:
|
||||
gst_vtenc_set_usage (self, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_BITRATE:
|
||||
gst_vtenc_set_bitrate (self, g_value_get_uint (value) * 1000 / 8);
|
||||
break;
|
||||
|
@ -295,14 +259,9 @@ static GstStateChangeReturn
|
|||
gst_vtenc_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstVTEnc *self = GST_VTENC_CAST (element);
|
||||
GError *error = NULL;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
|
||||
self->ctx = gst_core_media_ctx_new (GST_API_VIDEO_TOOLBOX, &error);
|
||||
if (error != NULL)
|
||||
goto api_error;
|
||||
|
||||
self->cur_outbufs = g_ptr_array_new ();
|
||||
}
|
||||
|
||||
|
@ -327,20 +286,9 @@ gst_vtenc_change_state (GstElement * element, GstStateChange transition)
|
|||
|
||||
g_ptr_array_free (self->cur_outbufs, TRUE);
|
||||
self->cur_outbufs = NULL;
|
||||
|
||||
g_object_unref (self->ctx);
|
||||
self->ctx = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
api_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("API error"),
|
||||
("%s", error->message));
|
||||
g_clear_error (&error);
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -434,7 +382,7 @@ gst_vtenc_negotiate_downstream (GstVTEnc * self, CMSampleBufferRef sbuf)
|
|||
"framerate", GST_TYPE_FRACTION,
|
||||
self->negotiated_fps_n, self->negotiated_fps_d, NULL);
|
||||
|
||||
if (self->details->format_id == kVTFormatH264) {
|
||||
if (self->details->format_id == kCMVideoCodecType_H264) {
|
||||
CMFormatDescriptionRef fmt;
|
||||
CFDictionaryRef atoms;
|
||||
CFStringRef avccKey;
|
||||
|
@ -506,8 +454,7 @@ gst_vtenc_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
if (self->options != NULL) {
|
||||
GST_INFO_OBJECT (self, "received PLI, will force intra");
|
||||
CFDictionaryAddValue (self->options,
|
||||
*(self->ctx->vt->kVTEncodeFrameOptionKey_ForceKeyFrame),
|
||||
kCFBooleanTrue);
|
||||
kVTEncodeFrameOptionKey_ForceKeyFrame, kCFBooleanTrue);
|
||||
} else {
|
||||
GST_INFO_OBJECT (self,
|
||||
"received PLI but encode not yet started, ignoring");
|
||||
|
@ -532,10 +479,8 @@ static VTCompressionSessionRef
|
|||
gst_vtenc_create_session (GstVTEnc * self)
|
||||
{
|
||||
VTCompressionSessionRef session = NULL;
|
||||
GstVTApi *vt = self->ctx->vt;
|
||||
CFMutableDictionaryRef pb_attrs;
|
||||
VTCompressionOutputCallback callback;
|
||||
VTStatus status;
|
||||
OSStatus status;
|
||||
|
||||
pb_attrs = CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
@ -544,15 +489,13 @@ gst_vtenc_create_session (GstVTEnc * self)
|
|||
gst_vtutil_dict_set_i32 (pb_attrs, kCVPixelBufferHeightKey,
|
||||
self->negotiated_height);
|
||||
|
||||
callback.func = gst_vtenc_enqueue_buffer;
|
||||
callback.data = self;
|
||||
|
||||
status = vt->VTCompressionSessionCreate (NULL,
|
||||
status = VTCompressionSessionCreate (NULL,
|
||||
self->negotiated_width, self->negotiated_height,
|
||||
self->details->format_id, 0, pb_attrs, 0, callback, &session);
|
||||
self->details->format_id, NULL, pb_attrs, NULL, gst_vtenc_enqueue_buffer,
|
||||
self, &session);
|
||||
GST_INFO_OBJECT (self, "VTCompressionSessionCreate for %d x %d => %d",
|
||||
self->negotiated_width, self->negotiated_height, status);
|
||||
if (status != kVTSuccess)
|
||||
self->negotiated_width, self->negotiated_height, (int) status);
|
||||
if (status != noErr)
|
||||
goto beach;
|
||||
|
||||
if (self->dump_properties) {
|
||||
|
@ -561,24 +504,21 @@ gst_vtenc_create_session (GstVTEnc * self)
|
|||
self->dump_properties = FALSE;
|
||||
}
|
||||
|
||||
gst_vtenc_session_configure_usage (self, session, gst_vtenc_get_usage (self));
|
||||
|
||||
gst_vtenc_session_configure_expected_framerate (self, session,
|
||||
(gdouble) self->negotiated_fps_n / (gdouble) self->negotiated_fps_d);
|
||||
gst_vtenc_session_configure_expected_duration (self, session,
|
||||
(gdouble) self->negotiated_fps_d / (gdouble) self->negotiated_fps_n);
|
||||
|
||||
status = vt->VTCompressionSessionSetProperty (session,
|
||||
*(vt->kVTCompressionPropertyKey_ProfileLevel),
|
||||
*(vt->kVTProfileLevel_H264_Baseline_3_0));
|
||||
status = VTSessionSetProperty (session,
|
||||
kVTCompressionPropertyKey_ProfileLevel,
|
||||
kVTProfileLevel_H264_Baseline_3_0);
|
||||
GST_DEBUG_OBJECT (self, "kVTCompressionPropertyKey_ProfileLevel => %d",
|
||||
status);
|
||||
(int) status);
|
||||
|
||||
status = vt->VTCompressionSessionSetProperty (session,
|
||||
*(vt->kVTCompressionPropertyKey_AllowTemporalCompression),
|
||||
kCFBooleanTrue);
|
||||
status = VTSessionSetProperty (session,
|
||||
kVTCompressionPropertyKey_AllowTemporalCompression, kCFBooleanTrue);
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"kVTCompressionPropertyKey_AllowTemporalCompression => %d", status);
|
||||
"kVTCompressionPropertyKey_AllowTemporalCompression => %d", (int) status);
|
||||
|
||||
gst_vtenc_session_configure_max_keyframe_interval (self, session, 0);
|
||||
gst_vtenc_session_configure_max_keyframe_interval_duration (self, session,
|
||||
|
@ -596,7 +536,7 @@ beach:
|
|||
static void
|
||||
gst_vtenc_destroy_session (GstVTEnc * self, VTCompressionSessionRef * session)
|
||||
{
|
||||
self->ctx->vt->VTCompressionSessionInvalidate (*session);
|
||||
VTCompressionSessionInvalidate (*session);
|
||||
if (*session != NULL) {
|
||||
CFRelease (*session);
|
||||
*session = NULL;
|
||||
|
@ -606,7 +546,6 @@ gst_vtenc_destroy_session (GstVTEnc * self, VTCompressionSessionRef * session)
|
|||
typedef struct
|
||||
{
|
||||
GstVTEnc *self;
|
||||
GstVTApi *vt;
|
||||
VTCompressionSessionRef session;
|
||||
} GstVTDumpPropCtx;
|
||||
|
||||
|
@ -616,7 +555,7 @@ gst_vtenc_session_dump_property (CFStringRef prop_name,
|
|||
{
|
||||
gchar *name_str;
|
||||
CFTypeRef prop_value;
|
||||
VTStatus status;
|
||||
OSStatus status;
|
||||
|
||||
name_str = gst_vtutil_string_to_utf8 (prop_name);
|
||||
if (dpc->self->dump_attributes) {
|
||||
|
@ -627,9 +566,8 @@ gst_vtenc_session_dump_property (CFStringRef prop_name,
|
|||
g_free (attrs_str);
|
||||
}
|
||||
|
||||
status = dpc->vt->VTCompressionSessionCopyProperty (dpc->session, prop_name,
|
||||
NULL, &prop_value);
|
||||
if (status == kVTSuccess) {
|
||||
status = VTSessionCopyProperty (dpc->session, prop_name, NULL, &prop_value);
|
||||
if (status == noErr) {
|
||||
gchar *value_str;
|
||||
|
||||
value_str = gst_vtutil_object_to_string (prop_value);
|
||||
|
@ -640,7 +578,7 @@ gst_vtenc_session_dump_property (CFStringRef prop_name,
|
|||
CFRelease (prop_value);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (dpc->self, "%s = <failed to query: %d>",
|
||||
name_str, status);
|
||||
name_str, (int) status);
|
||||
}
|
||||
|
||||
g_free (name_str);
|
||||
|
@ -650,13 +588,12 @@ static void
|
|||
gst_vtenc_session_dump_properties (GstVTEnc * self,
|
||||
VTCompressionSessionRef session)
|
||||
{
|
||||
GstVTDumpPropCtx dpc = { self, self->ctx->vt, session };
|
||||
GstVTDumpPropCtx dpc = { self, session };
|
||||
CFDictionaryRef dict;
|
||||
VTStatus status;
|
||||
OSStatus status;
|
||||
|
||||
status = self->ctx->vt->VTCompressionSessionCopySupportedPropertyDictionary
|
||||
(session, &dict);
|
||||
if (status != kVTSuccess)
|
||||
status = VTSessionCopySupportedPropertyDictionary (session, &dict);
|
||||
if (status != noErr)
|
||||
goto error;
|
||||
CFDictionaryApplyFunction (dict,
|
||||
(CFDictionaryApplierFunction) gst_vtenc_session_dump_property, &dpc);
|
||||
|
@ -668,20 +605,12 @@ error:
|
|||
GST_WARNING_OBJECT (self, "failed to dump properties");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vtenc_session_configure_usage (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, gint usage)
|
||||
{
|
||||
gst_vtenc_session_configure_property_int (self, session,
|
||||
*(self->ctx->vt->kVTCompressionPropertyKey_Usage), usage);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vtenc_session_configure_expected_framerate (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, gdouble framerate)
|
||||
{
|
||||
gst_vtenc_session_configure_property_double (self, session,
|
||||
*(self->ctx->vt->kVTCompressionPropertyKey_ExpectedFrameRate), framerate);
|
||||
kVTCompressionPropertyKey_ExpectedFrameRate, framerate);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -689,7 +618,7 @@ gst_vtenc_session_configure_expected_duration (GstVTEnc * self,
|
|||
VTCompressionSessionRef session, gdouble duration)
|
||||
{
|
||||
gst_vtenc_session_configure_property_double (self, session,
|
||||
*(self->ctx->vt->kVTCompressionPropertyKey_ExpectedDuration), duration);
|
||||
kVTCompressionPropertyKey_ExpectedDuration, duration);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -697,8 +626,7 @@ gst_vtenc_session_configure_max_keyframe_interval (GstVTEnc * self,
|
|||
VTCompressionSessionRef session, gint interval)
|
||||
{
|
||||
gst_vtenc_session_configure_property_int (self, session,
|
||||
*(self->ctx->vt->kVTCompressionPropertyKey_MaxKeyFrameInterval),
|
||||
interval);
|
||||
kVTCompressionPropertyKey_MaxKeyFrameInterval, interval);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -706,8 +634,7 @@ gst_vtenc_session_configure_max_keyframe_interval_duration (GstVTEnc * self,
|
|||
VTCompressionSessionRef session, gdouble duration)
|
||||
{
|
||||
gst_vtenc_session_configure_property_double (self, session,
|
||||
*(self->ctx->vt->kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration),
|
||||
duration);
|
||||
kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, duration);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -715,41 +642,41 @@ gst_vtenc_session_configure_bitrate (GstVTEnc * self,
|
|||
VTCompressionSessionRef session, guint bitrate)
|
||||
{
|
||||
gst_vtenc_session_configure_property_int (self, session,
|
||||
*(self->ctx->vt->kVTCompressionPropertyKey_AverageDataRate), bitrate);
|
||||
kVTCompressionPropertyKey_AverageBitRate, bitrate);
|
||||
}
|
||||
|
||||
static VTStatus
|
||||
static OSStatus
|
||||
gst_vtenc_session_configure_property_int (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, CFStringRef name, gint value)
|
||||
{
|
||||
CFNumberRef num;
|
||||
VTStatus status;
|
||||
OSStatus status;
|
||||
gchar name_str[128];
|
||||
|
||||
num = CFNumberCreate (NULL, kCFNumberIntType, &value);
|
||||
status = self->ctx->vt->VTCompressionSessionSetProperty (session, name, num);
|
||||
status = VTSessionSetProperty (session, name, num);
|
||||
CFRelease (num);
|
||||
|
||||
CFStringGetCString (name, name_str, sizeof (name_str), kCFStringEncodingUTF8);
|
||||
GST_DEBUG_OBJECT (self, "%s(%d) => %d", name_str, value, status);
|
||||
GST_DEBUG_OBJECT (self, "%s(%d) => %d", name_str, value, (int) status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VTStatus
|
||||
static OSStatus
|
||||
gst_vtenc_session_configure_property_double (GstVTEnc * self,
|
||||
VTCompressionSessionRef session, CFStringRef name, gdouble value)
|
||||
{
|
||||
CFNumberRef num;
|
||||
VTStatus status;
|
||||
OSStatus status;
|
||||
gchar name_str[128];
|
||||
|
||||
num = CFNumberCreate (NULL, kCFNumberDoubleType, &value);
|
||||
status = self->ctx->vt->VTCompressionSessionSetProperty (session, name, num);
|
||||
status = VTSessionSetProperty (session, name, num);
|
||||
CFRelease (num);
|
||||
|
||||
CFStringGetCString (name, name_str, sizeof (name_str), kCFStringEncodingUTF8);
|
||||
GST_DEBUG_OBJECT (self, "%s(%f) => %d", name_str, value, status);
|
||||
GST_DEBUG_OBJECT (self, "%s(%f) => %d", name_str, value, (int) status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -757,11 +684,10 @@ gst_vtenc_session_configure_property_double (GstVTEnc * self,
|
|||
static GstFlowReturn
|
||||
gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
||||
{
|
||||
GstVTApi *vt = self->ctx->vt;
|
||||
CMTime ts, duration;
|
||||
GstCoreMediaMeta *meta;
|
||||
CVPixelBufferRef pbuf = NULL;
|
||||
VTStatus vt_status;
|
||||
OSStatus vt_status;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
guint i;
|
||||
|
||||
|
@ -835,20 +761,19 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf)
|
|||
GST_OBJECT_LOCK (self);
|
||||
|
||||
self->expect_keyframe = CFDictionaryContainsKey (self->options,
|
||||
*(vt->kVTEncodeFrameOptionKey_ForceKeyFrame));
|
||||
kVTEncodeFrameOptionKey_ForceKeyFrame);
|
||||
if (self->expect_keyframe)
|
||||
gst_vtenc_clear_cached_caps_downstream (self);
|
||||
|
||||
vt_status = self->ctx->vt->VTCompressionSessionEncodeFrame (self->session,
|
||||
vt_status = VTCompressionSessionEncodeFrame (self->session,
|
||||
pbuf, ts, duration, self->options, NULL, NULL);
|
||||
|
||||
if (vt_status != 0) {
|
||||
GST_WARNING_OBJECT (self, "VTCompressionSessionEncodeFrame returned %d",
|
||||
vt_status);
|
||||
(int) vt_status);
|
||||
}
|
||||
|
||||
self->ctx->vt->VTCompressionSessionCompleteFrames (self->session,
|
||||
kCMTimeInvalid);
|
||||
VTCompressionSessionCompleteFrames (self->session, kCMTimeInvalid);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
|
@ -886,30 +811,32 @@ cv_error:
|
|||
}
|
||||
}
|
||||
|
||||
static VTStatus
|
||||
gst_vtenc_enqueue_buffer (void *data, int a2, int a3, int a4,
|
||||
CMSampleBufferRef sbuf, int a6, int a7)
|
||||
static void
|
||||
gst_vtenc_enqueue_buffer (void *outputCallbackRefCon,
|
||||
void *sourceFrameRefCon,
|
||||
OSStatus status,
|
||||
VTEncodeInfoFlags infoFlags, CMSampleBufferRef sampleBuffer)
|
||||
{
|
||||
GstVTEnc *self = data;
|
||||
GstVTEnc *self = outputCallbackRefCon;
|
||||
gboolean is_keyframe;
|
||||
GstBuffer *buf;
|
||||
|
||||
/* This may happen if we don't have enough bitrate */
|
||||
if (sbuf == NULL)
|
||||
if (sampleBuffer == NULL)
|
||||
goto beach;
|
||||
|
||||
is_keyframe = gst_vtenc_buffer_is_keyframe (self, sbuf);
|
||||
is_keyframe = gst_vtenc_buffer_is_keyframe (self, sampleBuffer);
|
||||
if (self->expect_keyframe) {
|
||||
if (!is_keyframe)
|
||||
goto beach;
|
||||
CFDictionaryRemoveValue (self->options,
|
||||
*(self->ctx->vt->kVTEncodeFrameOptionKey_ForceKeyFrame));
|
||||
kVTEncodeFrameOptionKey_ForceKeyFrame);
|
||||
}
|
||||
self->expect_keyframe = FALSE;
|
||||
|
||||
/* We are dealing with block buffers here, so we don't need
|
||||
* to enable the use of the video meta API on the core media buffer */
|
||||
buf = gst_core_media_buffer_new (sbuf, FALSE);
|
||||
buf = gst_core_media_buffer_new (sampleBuffer, FALSE);
|
||||
gst_buffer_copy_into (buf, self->cur_inbuf, GST_BUFFER_COPY_TIMESTAMPS,
|
||||
0, -1);
|
||||
if (is_keyframe) {
|
||||
|
@ -922,7 +849,7 @@ gst_vtenc_enqueue_buffer (void *data, int a2, int a3, int a4,
|
|||
g_ptr_array_add (self->cur_outbufs, buf);
|
||||
|
||||
beach:
|
||||
return kVTSuccess;
|
||||
return;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1013,7 +940,7 @@ gst_vtenc_register (GstPlugin * plugin,
|
|||
}
|
||||
|
||||
static const GstVTEncoderDetails gst_vtenc_codecs[] = {
|
||||
{"H.264", "h264", "video/x-h264", kVTFormatH264},
|
||||
{"H.264", "h264", "video/x-h264", kCMVideoCodecType_H264},
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include "coremediactx.h"
|
||||
#include <VideoToolbox/VideoToolbox.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -44,7 +43,7 @@ struct _GstVTEncoderDetails
|
|||
const gchar * name;
|
||||
const gchar * element_name;
|
||||
const gchar * mimetype;
|
||||
VTFormatId format_id;
|
||||
CMVideoCodecType format_id;
|
||||
};
|
||||
|
||||
struct _GstVTEncClass
|
||||
|
@ -61,11 +60,8 @@ struct _GstVTEnc
|
|||
GstPad * sinkpad;
|
||||
GstPad * srcpad;
|
||||
|
||||
gint usage;
|
||||
guint bitrate;
|
||||
|
||||
GstCoreMediaCtx * ctx;
|
||||
|
||||
gboolean dump_properties;
|
||||
gboolean dump_attributes;
|
||||
|
||||
|
|
Loading…
Reference in a new issue