Commit 7a66b16d authored by Thibault Saunier's avatar Thibault Saunier 🌵 Committed by Thibault Saunier

Import GstTranscoder

parent 87311d40
encoding_targetsdir = join_paths(get_option('datadir'),
'gstreamer-' + api_version, 'encoding-profiles')
encoding_targets = [
['file-extension', ['targets/file-extension/ogv.gep',
'targets/file-extension/oga.gep',
'targets/file-extension/mkv.gep',
'targets/file-extension/mp3.gep',
'targets/file-extension/webm.gep',
'targets/file-extension/flv.gep',
'targets/file-extension/mp4.gep',
'targets/file-extension/avi.gep',],
],
['online-services', ['targets/online-service/youtube.gep',]],
['device', ['targets/device/dvd.gep',]],
]
foreach path_targets : encoding_targets
dir = join_paths(encoding_targetsdir, path_targets.get(0))
etargets = path_targets.get(1)
install_data(sources: etargets, install_dir: dir)
endforeach
[GStreamer Encoding Target]
name=dvd
category=device
description=Encoding target suitable for DVDs
[profile-dvd]
name=dvd
type=container
description[c]=This is an encoding profile usable for DVDs
format=video/mpeg, mpegversion=(int)2, systemstream=(boolean)true
[streamprofile-dvd-0]
parent=dvd
type=video
format=video/mpeg, mpegversion=(int)2, systemstream=(boolean)false
presence=0
pass=0
variableframerate=false
[streamprofile-dvd-1]
parent=dvd
type=audio
format=audio/mpeg, mpegversion=(int)1, layer=(int)2
presence=0
[GStreamer Encoding Target]
name=avi
category=file-extension
description=Default target for files with a .avi extension
[profile-default]
name=default
type=container
description=Default profile for files with a .avi extension.
format=video/x-msvideo
[streamprofile-default-0]
parent=default
type=audio
format=audio/mpeg, mpegversion=(int)1, mpegaudioversion=(int)1, layer=(int)3
[streamprofile-default-1]
parent=default
type=video
format=video/mpeg, mpegversion=(int)4
[GStreamer Encoding Target]
name=flv
category=file-extension
description=Default target for files with a .flv extension
[profile-default]
name=default
type=container
description=Default profile for files with a .flv extension.
format=video/x-flv
[streamprofile-default-0]
parent=default
type=audio
format=audio/mpeg,mpegversion=4
[streamprofile-default-1]
parent=default
type=audio
format=audio/mpeg, mpegversion=(int)1, mpegaudioversion=(int)1, layer=(int)3
[streamprofile-default-2]
parent=default
type=video
format=video/x-h264
preset=Profile YouTube
pass=0
[streamprofile-default-3]
parent=default
type=video
format=video/x-h264
[GStreamer Encoding Target]
name=mkv;matroska;
category=file-extension
description=Default target for files with a .mkv extension
[profile-default]
name=default
description=Default profile for files with a .mkv extension. Audio stream can be either opus (default) or vorbis depending on what is available on the system. Video stream will be either in vp8 (default) or vp9.
type=container
format=video/x-matroska
[streamprofile-default-0]
parent=default
type=audio
format=audio/x-vorbis;audio/x-opus
[streamprofile-default-1]
parent=default
type=video
format=video/x-h264
preset=Quality Normal
pass=0
[streamprofile-default-2]
parent=default
type=video
format=video/x-h264
pass=0
[GStreamer Encoding Target]
name=mp3
category=file-extension
description=Default target for files with a .mp3 extension
[profile-default]
name=default
type=container
description=Default profile for files with a .mp3 extension.
format=application/x-id3
[streamprofile-default-0]
parent=default
type=audio
format=audio/mpeg, mpegversion=(int)1, mpegaudioversion=(int)1, layer=(int)3
[GStreamer Encoding Target]
name=mp4;mov
category=file-extension
description=Default target for files with a .mp4 and .mov extension
[profile-default]
name=default
type=container
description=Default profile for files with a .mp4 extension. Suitable for uploading to youtube.
format=video/quicktime
preset=Profile YouTube
[streamprofile-default-0]
parent=default
type=audio
format=audio/mpeg,mpegversion=4,base-profile=lc,rate={48000,96000},channels=2;audio/mpeg,mpegversion=4,base-profile=lc,rate={48000,96000}
restriction=audio/x-raw,channels=6,channel-mask=0x3f;audio/x-raw,channels=2
[streamprofile-default-1]
parent=default
type=video
format=video/x-h264
preset=Profile YouTube
pass=0
[streamprofile-default-2]
parent=default
type=audio
format=audio/mpeg,mpegversion=4
[streamprofile-default-3]
parent=default
type=video
format=video/x-h264
[GStreamer Encoding Target]
name=oga
category=file-extension
description=Default target for files with a .ogg and friends extension
[profile-default]
name=default
description=Default target for files with a .ogg and friends extension
type=container
format=audio/ogg
[streamprofile-default-0]
parent=default
type=audio
format=audio/x-vorbis;audio/x-opus
[GStreamer Encoding Target]
name=ogv;ogg
category=file-extension
description=Default target for files with a .ogg and friends extension
[profile-default]
name=default
description=Default target for files with a .ogg and friends extension
type=container
format=application/ogg
[streamprofile-default-0]
parent=default
type=audio
format=audio/x-vorbis;audio/x-opus
[streamprofile-default-1]
parent=default
type=video
format=video/x-theora
[streamprofile-default-2]
parent=default
type=video
format=video/x-vp8
[GStreamer Encoding Target]
name=webm
category=file-extension
description=Default target for files with a .webm extension
[profile-default]
name=default
description=Default profile for files with a .webm extension. Audio stream can be either vorbis (default) or opus depending on what is available on the system. Video stream will be either in vp8 (default) or vp9.
type=container
format=video/webm
[streamprofile-default-0]
parent=default
type=audio
format=audio/x-vorbis;audio/x-opus
[streamprofile-default-1]
parent=default
type=video
format=video/x-vp8;video/x-vp9
pass=0
[GStreamer Encoding Target]
name=youtube;yt
category=online-service
description=Recommended encoding settings for YouTube
[profile-default]
name=default
type=container
description=Youtube recommended profile with automatic audio setting
format=video/quicktime
preset=Profile YouTube
[streamprofile-default-0]
parent=default
type=audio
format=audio/mpeg,mpegversion=4,base-profile=lc
restriction=audio/x-raw,channels=6,rate={48000,96000};audio/x-raw,channels=2,rate={48000,96000}
[streamprofile-default-1]
parent=default
type=video
format=video/x-h264,profile=high
preset=Profile YouTube
pass=0
This diff is collapsed.
# GstTranscoder
High level API to transcode streams
This library should be linked to by getting cflags and libs from
gstreamer-transcoder-{{ gst_api_version.md }}
> NOTE: This library API is considered *unstable*
...@@ -103,6 +103,7 @@ if build_gir ...@@ -103,6 +103,7 @@ if build_gir
{'name': 'adaptivedemux', 'lib': gstadaptivedemux_dep}, {'name': 'adaptivedemux', 'lib': gstadaptivedemux_dep},
{'name': 'webrtc', 'gir': webrtc_gir, 'lib': gstwebrtc_dep, 'suffix': 'lib'}, {'name': 'webrtc', 'gir': webrtc_gir, 'lib': gstwebrtc_dep, 'suffix': 'lib'},
{'name': 'audio', 'gir': audio_gir, 'lib': gstbadaudio_dep, 'prefix': 'bad-'}, {'name': 'audio', 'gir': audio_gir, 'lib': gstbadaudio_dep, 'prefix': 'bad-'},
{'name': 'transcoder', 'gir': transcoder_gir, 'lib': gst_transcoder_dep},
] ]
endif endif
......
...@@ -11,6 +11,7 @@ subdir('mpegts') ...@@ -11,6 +11,7 @@ subdir('mpegts')
subdir('opencv') subdir('opencv')
subdir('player') subdir('player')
subdir('sctp') subdir('sctp')
subdir('transcoder')
subdir('vulkan') subdir('vulkan')
subdir('wayland') subdir('wayland')
subdir('webrtc') subdir('webrtc')
This diff is collapsed.
#ifndef __GST_TRANSCODER_H
#define __GST_TRANSCODER_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
#include "transcoder-prelude.h"
G_BEGIN_DECLS
typedef struct _GstTranscoderSignalDispatcher GstTranscoderSignalDispatcher;
typedef struct _GstTranscoderSignalDispatcherInterface GstTranscoderSignalDispatcherInterface;
/*********** Error definitions ************/
#define GST_TRANSCODER_ERROR (gst_transcoder_error_quark ())
#define GST_TYPE_TRANSCODER_ERROR (gst_transcoder_error_get_type ())
/**
* GstTranscoderError:
* @GST_TRANSCODER_ERROR_FAILED: generic error.
*/
typedef enum {
GST_TRANSCODER_ERROR_FAILED = 0
} GstTranscoderError;
GST_TRANSCODER_API
GQuark gst_transcoder_error_quark (void);
GST_TRANSCODER_API
GType gst_transcoder_error_get_type (void);
GST_TRANSCODER_API
const gchar * gst_transcoder_error_get_name (GstTranscoderError error);
/*********** GstTranscoder definition ************/
#define GST_TYPE_TRANSCODER (gst_transcoder_get_type ())
#define GST_TRANSCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TRANSCODER, GstTranscoder))
#define GST_TRANSCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TRANSCODER, GstTranscoderClass))
#define GST_IS_TRANSCODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TRANSCODER))
#define GST_IS_TRANSCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TRANSCODER))
#define GST_TRANSCODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TRANSCODER, GstTranscoderClass))
typedef struct _GstTranscoder GstTranscoder;
typedef struct _GstTranscoderClass GstTranscoderClass;
typedef struct _GstTranscoderPrivate GstTranscoderPrivate;
GST_TRANSCODER_API
GType gst_transcoder_get_type (void);
GST_TRANSCODER_API
GstTranscoder * gst_transcoder_new (const gchar * source_uri,
const gchar * dest_uri,
const gchar * encoding_profile);
GST_TRANSCODER_API
GstTranscoder * gst_transcoder_new_full (const gchar * source_uri,
const gchar * dest_uri,
GstEncodingProfile *profile,
GstTranscoderSignalDispatcher *signal_dispatcher);
GST_TRANSCODER_API
gboolean gst_transcoder_run (GstTranscoder *self,
GError ** error);
GST_TRANSCODER_API
void gst_transcoder_set_cpu_usage (GstTranscoder *self,
gint cpu_usage);
GST_TRANSCODER_API
void gst_transcoder_run_async (GstTranscoder *self);
GST_TRANSCODER_API
void gst_transcoder_set_position_update_interval (GstTranscoder *self,
guint interval);
GST_TRANSCODER_API
gchar * gst_transcoder_get_source_uri (GstTranscoder * self);
GST_TRANSCODER_API
gchar * gst_transcoder_get_dest_uri (GstTranscoder * self);
GST_TRANSCODER_API
guint gst_transcoder_get_position_update_interval (GstTranscoder *self);
GST_TRANSCODER_API
GstClockTime gst_transcoder_get_position (GstTranscoder * self);
GST_TRANSCODER_API
GstClockTime gst_transcoder_get_duration (GstTranscoder * self);
GST_TRANSCODER_API
GstElement * gst_transcoder_get_pipeline (GstTranscoder * self);
GST_TRANSCODER_API
gboolean gst_transcoder_get_avoid_reencoding (GstTranscoder * self);
GST_TRANSCODER_API
void gst_transcoder_set_avoid_reencoding (GstTranscoder * self,
gboolean avoid_reencoding);
/****************** Signal dispatcher *******************************/
#define GST_TYPE_TRANSCODER_SIGNAL_DISPATCHER (gst_transcoder_signal_dispatcher_get_type ())
#define GST_TRANSCODER_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TRANSCODER_SIGNAL_DISPATCHER, GstTranscoderSignalDispatcher))
#define GST_IS_TRANSCODER_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TRANSCODER_SIGNAL_DISPATCHER))
#define GST_TRANSCODER_SIGNAL_DISPATCHER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_TRANSCODER_SIGNAL_DISPATCHER, GstTranscoderSignalDispatcherInterface))
struct _GstTranscoderSignalDispatcherInterface {
GTypeInterface parent_iface;
void (*dispatch) (GstTranscoderSignalDispatcher * self,
GstTranscoder * transcoder,
void (*emitter) (gpointer data),
gpointer data,
GDestroyNotify destroy);
};
typedef struct _GstTranscoderGMainContextSignalDispatcher GstTranscoderGMainContextSignalDispatcher;
typedef struct _GstTranscoderGMainContextSignalDispatcherClass GstTranscoderGMainContextSignalDispatcherClass;
GST_TRANSCODER_API
GType gst_transcoder_signal_dispatcher_get_type (void);
#define GST_TYPE_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER (gst_transcoder_g_main_context_signal_dispatcher_get_type ())
#define GST_IS_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER))
#define GST_IS_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER))
#define GST_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER, GstTranscoderGMainContextSignalDispatcherClass))
#define GST_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER, GstTranscoderGMainContextSignalDispatcher))
#define GST_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER, GstTranscoderGMainContextSignalDispatcherClass))
#define GST_TRANSCODER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_CAST(obj) ((GstTranscoderGMainContextSignalDispatcher*)(obj))
GST_TRANSCODER_API
GType gst_transcoder_g_main_context_signal_dispatcher_get_type (void);
GST_TRANSCODER_API
GstTranscoderSignalDispatcher * gst_transcoder_g_main_context_signal_dispatcher_new (GMainContext * application_context);
G_END_DECLS
#endif
sources = files(['gsttranscoder.c'])
headers = files(['gsttranscoder.h', 'transcoder-prelude.h'])
install_headers(headers, subdir : 'gstreamer-' + api_version + '/gst/transcoder')
gst_transcoder = library('gsttranscoder-' + api_version,
sources,
install: true,
include_directories : [configinc, libsinc],
dependencies: [gst_dep, gstpbutils_dep],
c_args: gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API', '-DBUILDING_GST_TRANSCODER'],
soversion : soversion,
)
if build_gir
transcoder_gir = gnome.generate_gir(gst_transcoder,
sources : sources + headers,
nsversion : api_version,
namespace : 'GstTranscoder',
identifier_prefix : 'Gst',
symbol_prefix : 'gst_',
includes : ['GObject-2.0',
'Gst-' + api_version,
'GstPbutils-' + api_version],
dependencies: [gst_dep, gstpbutils_dep],
install : true,
extra_args : ['--add-init-section=extern gboolean gst_init(gint *argc, gchar **argv); gst_init(NULL,NULL);']
)
endif
gst_transcoder_dep = declare_dependency(link_with: gst_transcoder,
dependencies : [gst_dep, gstpbutils_dep],
include_directories : [libsinc]
)
\ No newline at end of file
/* GStreamer Transcoder Library
*
* Copyright (C) 2019 Thibault Saunier <tsaunier@igalia.com>
*
* transcoder-prelude.h: prelude include header for the gst-transcoder library
*
* 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_TRANSCODER_PRELUDE_H__
#define __GST_TRANSCODER_PRELUDE_H__
#include <gst/gst.h>
#ifndef GST_TRANSCODER_API
# ifdef BUILDING_GST_TRANSCODER
# define GST_TRANSCODER_API GST_API_EXPORT /* from config.h */
# else
# define GST_TRANSCODER_API GST_API_IMPORT
# endif
#endif
#endif /* __GST_TRANSCODER_PRELUDE_H__ */
...@@ -9,7 +9,7 @@ foreach plugin : ['accurip', 'adpcmdec', 'adpcmenc', 'aiff', 'asfmux', ...@@ -9,7 +9,7 @@ foreach plugin : ['accurip', 'adpcmdec', 'adpcmenc', 'aiff', 'asfmux',
'midi', 'mpegdemux', 'mpegpsmux', 'mpegtsdemux', 'mpegtsmux', 'midi', 'mpegdemux', 'mpegpsmux', 'mpegtsdemux', 'mpegtsmux',
'mxf', 'netsim', 'onvif', 'pcapparse', 'pnm', 'proxy', 'mxf', 'netsim', 'onvif', 'pcapparse', 'pnm', 'proxy',
'rawparse', 'removesilence', 'rist', 'rtp', 'sdp', 'segmentclip', 'rawparse', 'removesilence', 'rist', 'rtp', 'sdp', 'segmentclip',
'siren', 'smooth', 'speed', 'subenc', 'timecode', 'siren', 'smooth', 'speed', 'subenc', 'timecode', 'transcode',
'videofilters', 'videoframe_audiolevel', 'videoparsers', 'videofilters', 'videoframe_audiolevel', 'videoparsers',
'videosignal', 'vmnc', 'y4m', 'yadif'] 'videosignal', 'vmnc', 'y4m', 'yadif']
if not get_option(plugin).disabled() if not get_option(plugin).disabled()
......
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_GETRUSAGE
#include "gst-cpu-throttling-clock.h"
#include <unistd.h>
#include <sys/resource.h>
#include "gst-cpu-throttling-clock.h"
/**
* SECTION: gst-cpu-throttling-clock
* @title: GstCpuThrottlingClock
* @short_description: TODO
*
* TODO
*/
/* *INDENT-OFF* */
GST_DEBUG_CATEGORY_STATIC (gst_cpu_throttling_clock_debug);
#define GST_CAT_DEFAULT gst_cpu_throttling_clock_debug
struct _GstCpuThrottlingClockPrivate
{
guint wanted_cpu_usage;
GstClock *sclock;
GstClockTime current_wait_time;
GstPoll *timer;
struct rusage last_usage;
GstClockID evaluate_wait_time;
GstClockTime time_between_evals;
};
#define parent_class gst_cpu_throttling_clock_parent_class
G_DEFINE_TYPE_WITH_CODE (GstCpuThrottlingClock, gst_cpu_throttling_clock, GST_TYPE_CLOCK, G_ADD_PRIVATE(GstCpuThrottlingClock))
enum
{
PROP_FIRST,
PROP_CPU_USAGE,
PROP_LAST
};
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
/* *INDENT-ON* */
static void
gst_cpu_throttling_clock_get_property (GObject * object,
guint property_id, GValue * value, GParamSpec * pspec)
{
GstCpuThrottlingClock *self = GST_CPU_THROTTLING_CLOCK (object);
switch (property_id) {
case PROP_CPU_USAGE:
g_value_set_uint (value, self->priv->wanted_cpu_usage);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gst_cpu_throttling_clock_set_property (GObject * object,
guint property_id, const GValue * value, GParamSpec * pspec)
{
GstCpuThrottlingClock *self = GST_CPU_THROTTLING_CLOCK (object);
switch (property_id) {
case PROP_CPU_USAGE:
self->priv->wanted_cpu_usage = g_value_get_uint (value);
if (self->priv->wanted_cpu_usage == 0)
self->priv->wanted_cpu_usage = 100;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gboolean
gst_transcoder_adjust_wait_time (GstClock * sync_clock, GstClockTime time,
GstClockID id, GstCpuThrottlingClock * self)
{
struct rusage ru;
float delta_usage, usage, coef;
GstCpuThrottlingClockPrivate *priv = self->priv;
getrusage (RUSAGE_SELF, &ru);
delta_usage = GST_TIMEVAL_TO_TIME (ru.ru_utime) -
GST_TIMEVAL_TO_TIME (self->priv->last_usage.ru_utime);
usage =
((float) delta_usage / self->priv->time_between_evals * 100) /
g_get_num_processors ();
self->priv->last_usage = ru;
coef = GST_MSECOND / 10;
if (usage < (gfloat) priv->wanted_cpu_usage) {
coef = -coef;
}
priv->current_wait_time = CLAMP (0,
(GstClockTime) priv->current_wait_time + coef, GST_SECOND);
GST_DEBUG_OBJECT (self,
"Avg is %f (wanted %d) => %" GST_TIME_FORMAT, usage,
self->priv->wanted_cpu_usage, GST_TIME_ARGS (priv->current_wait_time));
return TRUE;
}
static GstClockReturn
_wait (GstClock * clock, GstClockEntry * entry, GstClockTimeDiff * jitter)
{
GstCpuThrottlingClock *self = GST_CPU_THROTTLING_CLOCK (clock);
if (!self->priv->evaluate_wait_time) {
if (!(self->priv->sclock)) {
GST_ERROR_OBJECT (clock, "Could not find any system clock"
" to start the wait time evaluation task");
} else {
self->priv->evaluate_wait_time =
gst_clock_new_periodic_id (self->priv->sclock,
gst_clock_get_time (self->priv->sclock),
self->priv->time_between_evals);
gst_clock_id_wait_async (self->priv->evaluate_wait_time,
(GstClockCallback) gst_transcoder_adjust_wait_time,
(gpointer) self, NULL);
}
}
if (G_UNLIKELY (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED))
return GST_CLOCK_UNSCHEDULED;
if (gst_poll_wait (self->priv->timer, self->priv->current_wait_time)) {
GST_INFO_OBJECT (self, "Something happened on the poll");
}
return GST_CLOCK_ENTRY_STATUS (entry);
}
static GstClockTime
_get_internal_time (GstClock * clock)
{
GstCpuThrottlingClock *self = GST_CPU_THROTTLING_CLOCK (clock);
return gst_clock_get_internal_time (self->priv->sclock);
}
static void
gst_cpu_throttling_clock_dispose (GObject * object)
{
GstCpuThrottlingClock *self = GST_CPU_THROTTLING_CLOCK (object);
if (self->priv->evaluate_wait_time) {
gst_clock_id_unschedule (self->priv->evaluate_wait_time);
gst_clock_id_unref (self->priv->evaluate_wait_time);
self->priv->evaluate_wait_time = 0;
}
}
static void
gst_cpu_throttling_clock_class_init (GstCpuThrottlingClockClass * klass)
{
GObjectClass *oclass = G_OBJECT_CLASS (klass);
GstClockClass *clock_klass = GST_CLOCK_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (gst_cpu_throttling_clock_debug, "cpuclock", 0,
"UriTranscodebin element");
oclass->get_property = gst_cpu_throttling_clock_get_property;
oclass->set_property = gst_cpu_throttling_clock_set_property;
oclass->dispose = gst_cpu_throttling_clock_dispose;
/**
* GstCpuThrottlingClock:cpu-usage:
*
* Since: UNRELEASED
*/
param_specs[PROP_CPU_USAGE] = g_param_spec_uint ("cpu-usage", "cpu-usage",