mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
Merge branch 'master' into 0.11
Conflicts: NEWS RELEASE configure.ac docs/plugins/gst-plugins-base-plugins.args docs/plugins/gst-plugins-base-plugins.hierarchy docs/plugins/gst-plugins-base-plugins.interfaces docs/plugins/inspect/plugin-adder.xml docs/plugins/inspect/plugin-alsa.xml docs/plugins/inspect/plugin-app.xml docs/plugins/inspect/plugin-audioconvert.xml docs/plugins/inspect/plugin-audiorate.xml docs/plugins/inspect/plugin-audioresample.xml docs/plugins/inspect/plugin-audiotestsrc.xml docs/plugins/inspect/plugin-cdparanoia.xml docs/plugins/inspect/plugin-encoding.xml docs/plugins/inspect/plugin-ffmpegcolorspace.xml docs/plugins/inspect/plugin-gdp.xml docs/plugins/inspect/plugin-gio.xml docs/plugins/inspect/plugin-gnomevfs.xml docs/plugins/inspect/plugin-libvisual.xml docs/plugins/inspect/plugin-ogg.xml docs/plugins/inspect/plugin-pango.xml docs/plugins/inspect/plugin-playback.xml docs/plugins/inspect/plugin-subparse.xml docs/plugins/inspect/plugin-tcp.xml docs/plugins/inspect/plugin-theora.xml docs/plugins/inspect/plugin-typefindfunctions.xml docs/plugins/inspect/plugin-uridecodebin.xml docs/plugins/inspect/plugin-videorate.xml docs/plugins/inspect/plugin-videoscale.xml docs/plugins/inspect/plugin-videotestsrc.xml docs/plugins/inspect/plugin-volume.xml docs/plugins/inspect/plugin-vorbis.xml docs/plugins/inspect/plugin-ximagesink.xml docs/plugins/inspect/plugin-xvimagesink.xml gst-libs/gst/app/gstappsink.c gst-libs/gst/audio/mixer.c gst-libs/gst/audio/mixer.h gst-libs/gst/tag/gstxmptag.c gst-libs/gst/video/colorbalance.c gst-libs/gst/video/colorbalance.h gst/adder/gstadder.c gst/playback/gstplaybasebin.c gst/playback/gstplaybin2.c gst/playback/gstplaysink.c gst/videoscale/gstvideoscale.c tests/check/elements/videoscale.c tests/examples/seek/seek.c tests/examples/v4l/probe.c win32/common/_stdint.h win32/common/audio-enumtypes.c win32/common/config.h
This commit is contained in:
commit
f7939bb43f
30 changed files with 3264 additions and 1234 deletions
|
@ -35,6 +35,9 @@ then
|
|||
ln -s ../../common/hooks/pre-commit.hook .git/hooks/pre-commit
|
||||
fi
|
||||
|
||||
# GNU gettext automake support doesn't get along with git.
|
||||
# https://bugzilla.gnome.org/show_bug.cgi?id=661128
|
||||
touch -t 200001010000 po/gst-plugins-base-0.10.pot
|
||||
|
||||
CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-gtk-doc'
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
|
||||
* with newer GLib versions (>= 2.31.0) */
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
|
|
@ -1361,7 +1361,7 @@ theora_enc_encode_and_push (GstTheoraEnc * enc, ogg_packet op,
|
|||
GstClockTime next_time, duration;
|
||||
GstClockTime timestamp = 0;
|
||||
GST_DEBUG_OBJECT (enc, "encoded. granule:%" G_GINT64_FORMAT ", packet:%p, "
|
||||
"bytes:%ld", op.granulepos, op.packet, op.bytes);
|
||||
"bytes:%ld", (gint64) op.granulepos, op.packet, op.bytes);
|
||||
|
||||
next_time = th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
|
||||
duration = next_time - enc->next_ts;
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
* Last reviewed on 2008-05-28 (0.10.20)
|
||||
*/
|
||||
|
||||
/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
|
||||
* with newer GLib versions (>= 2.31.0) */
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
|
|
@ -158,6 +158,7 @@ static gboolean gst_app_sink_unlock_stop (GstBaseSink * bsink);
|
|||
static gboolean gst_app_sink_start (GstBaseSink * psink);
|
||||
static gboolean gst_app_sink_stop (GstBaseSink * psink);
|
||||
static gboolean gst_app_sink_event (GstBaseSink * sink, GstEvent * event);
|
||||
static gboolean gst_app_sink_query (GstBaseSink * bsink, GstQuery * query);
|
||||
static GstFlowReturn gst_app_sink_preroll (GstBaseSink * psink,
|
||||
GstBuffer * buffer);
|
||||
static GstFlowReturn gst_app_sink_render (GstBaseSink * psink,
|
||||
|
@ -337,6 +338,7 @@ gst_app_sink_class_init (GstAppSinkClass * klass)
|
|||
basesink_class->render = gst_app_sink_render;
|
||||
basesink_class->get_caps = gst_app_sink_getcaps;
|
||||
basesink_class->set_caps = gst_app_sink_setcaps;
|
||||
basesink_class->query = gst_app_sink_query;
|
||||
|
||||
klass->pull_preroll = gst_app_sink_pull_preroll;
|
||||
klass->pull_sample = gst_app_sink_pull_sample;
|
||||
|
@ -774,6 +776,30 @@ gst_app_sink_getcaps (GstBaseSink * psink, GstCaps * filter)
|
|||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_app_sink_query (GstBaseSink * bsink, GstQuery * query)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_SEEKING:{
|
||||
GstFormat fmt;
|
||||
|
||||
/* we don't supporting seeking */
|
||||
gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
|
||||
gst_query_set_seeking (query, fmt, FALSE, 0, -1);
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* external API */
|
||||
|
||||
/**
|
||||
|
|
|
@ -83,9 +83,8 @@ gst_mixer_get_type (void)
|
|||
static void
|
||||
gst_mixer_class_init (GstMixerInterface * iface)
|
||||
{
|
||||
iface->mixer_type = GST_MIXER_SOFTWARE;
|
||||
|
||||
/* default virtual functions */
|
||||
iface->get_mixer_type = NULL;
|
||||
iface->list_tracks = NULL;
|
||||
iface->set_volume = NULL;
|
||||
iface->get_volume = NULL;
|
||||
|
@ -304,7 +303,8 @@ gst_mixer_get_mixer_type (GstMixer * mixer)
|
|||
{
|
||||
GstMixerInterface *iface = GST_MIXER_GET_INTERFACE (mixer);
|
||||
|
||||
return iface->mixer_type;
|
||||
g_return_val_if_fail (iface->get_mixer_type != NULL, GST_MIXER_SOFTWARE);
|
||||
return iface->get_mixer_type (mixer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,8 +37,6 @@ G_BEGIN_DECLS
|
|||
#define GST_MIXER_GET_INTERFACE(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER, GstMixerInterface))
|
||||
|
||||
#define GST_MIXER_TYPE(iface) (iface->mixer_type)
|
||||
|
||||
typedef struct _GstMixer GstMixer;
|
||||
typedef struct _GstMixerInterface GstMixerInterface;
|
||||
|
||||
|
@ -112,8 +110,6 @@ typedef enum
|
|||
struct _GstMixerInterface {
|
||||
GTypeInterface iface;
|
||||
|
||||
GstMixerType mixer_type;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_tracks) (GstMixer *mixer);
|
||||
|
||||
|
@ -137,6 +133,8 @@ struct _GstMixerInterface {
|
|||
GstMixerOptions *opts);
|
||||
|
||||
GstMixerFlags (* get_mixer_flags) (GstMixer *mixer);
|
||||
|
||||
GstMixerType (* get_mixer_type) (GstMixer *mixer);
|
||||
};
|
||||
|
||||
GType gst_mixer_get_type (void);
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
* </refsect2>
|
||||
*/
|
||||
|
||||
/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
|
||||
* with newer GLib versions (>= 2.31.0) */
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct _GstNavigationInterface GstNavigationInterface;
|
|||
* @iface: the parent interface
|
||||
* @send_event: sending a navigation event
|
||||
*
|
||||
* Color-balance interface.
|
||||
* Navigation interface.
|
||||
*/
|
||||
struct _GstNavigationInterface {
|
||||
GTypeInterface iface;
|
||||
|
|
|
@ -173,9 +173,11 @@ xmp_tag_type_get_name (GstXmpTagType tagtype)
|
|||
case GstXmpTagTypeBag:
|
||||
return "rdf:Bag";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
return NULL; /* make compiler happy with -DG_DISABLE_ASSERT */
|
||||
|
||||
/* Make compiler happy */
|
||||
g_return_val_if_reached ("");
|
||||
}
|
||||
|
||||
struct _PendingXmpTag
|
||||
|
|
|
@ -106,12 +106,11 @@ gst_color_balance_class_init (GstColorBalanceInterface * iface)
|
|||
initialized = TRUE;
|
||||
}
|
||||
|
||||
iface->balance_type = GST_COLOR_BALANCE_SOFTWARE;
|
||||
|
||||
/* default virtual functions */
|
||||
iface->list_channels = NULL;
|
||||
iface->set_value = NULL;
|
||||
iface->get_value = NULL;
|
||||
iface->get_balance_type = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,7 +214,10 @@ gst_color_balance_get_balance_type (GstColorBalance * balance)
|
|||
|
||||
iface = GST_COLOR_BALANCE_GET_INTERFACE (balance);
|
||||
|
||||
return iface->balance_type;
|
||||
g_return_val_if_fail (iface->get_balance_type != NULL,
|
||||
GST_COLOR_BALANCE_SOFTWARE);
|
||||
|
||||
return iface->get_balance_type (balance);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,8 +36,6 @@ G_BEGIN_DECLS
|
|||
#define GST_COLOR_BALANCE_GET_INTERFACE(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_COLOR_BALANCE, GstColorBalanceInterface))
|
||||
|
||||
#define GST_COLOR_BALANCE_TYPE(iface) (iface->balance_type)
|
||||
|
||||
typedef struct _GstColorBalance GstColorBalance;
|
||||
typedef struct _GstColorBalanceInterface GstColorBalanceInterface;
|
||||
|
||||
|
@ -73,8 +71,6 @@ typedef enum
|
|||
struct _GstColorBalanceInterface {
|
||||
GTypeInterface iface;
|
||||
|
||||
GstColorBalanceType balance_type;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_channels) (GstColorBalance *balance);
|
||||
|
||||
|
@ -83,11 +79,15 @@ struct _GstColorBalanceInterface {
|
|||
gint value);
|
||||
gint (* get_value) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel);
|
||||
GstColorBalanceType (*get_balance_type) (GstColorBalance *balance);
|
||||
|
||||
/* signals */
|
||||
void (* value_changed) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING-1];
|
||||
};
|
||||
|
||||
GType gst_color_balance_get_type (void);
|
||||
|
|
|
@ -116,8 +116,8 @@ static gboolean gst_adder_sink_query (GstPad * pad, GstObject * parent,
|
|||
GstQuery * query);
|
||||
static gboolean gst_adder_src_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event);
|
||||
static gboolean gst_adder_sink_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event);
|
||||
static gboolean gst_adder_sink_event (GstCollectPads2 * pads,
|
||||
GstCollectData2 * pad, GstEvent * event, gpointer user_data);
|
||||
|
||||
static GstPad *gst_adder_request_new_pad (GstElement * element,
|
||||
GstPadTemplate * temp, const gchar * unused, const GstCaps * caps);
|
||||
|
@ -131,8 +131,6 @@ static GstFlowReturn gst_adder_do_clip (GstCollectPads2 * pads,
|
|||
gpointer user_data);
|
||||
static GstFlowReturn gst_adder_collected (GstCollectPads2 * pads,
|
||||
gpointer user_data);
|
||||
static gboolean gst_adder_event (GstCollectPads2 * pads, GstCollectData2 * pad,
|
||||
GstEvent * event, gpointer user_data);
|
||||
|
||||
/* non-clipping versions (for float) */
|
||||
#define MAKE_FUNC_NC(name,type) \
|
||||
|
@ -561,6 +559,8 @@ gst_adder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* event handling */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstEvent *event;
|
||||
|
@ -763,14 +763,13 @@ done:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_adder_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||
gst_adder_sink_event (GstCollectPads2 * pads, GstCollectData2 * pad,
|
||||
GstEvent * event, gpointer user_data)
|
||||
{
|
||||
GstAdder *adder;
|
||||
gboolean ret = TRUE;
|
||||
GstAdder *adder = GST_ADDER (user_data);
|
||||
gboolean res = FALSE;
|
||||
|
||||
adder = GST_ADDER (parent);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "Got %s event on sink pad",
|
||||
GST_DEBUG_OBJECT (pad->pad, "Got %s event on sink pad",
|
||||
GST_EVENT_TYPE_NAME (event));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
|
@ -779,34 +778,40 @@ gst_adder_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
ret = gst_adder_setcaps (adder, pad, caps);
|
||||
res = gst_adder_setcaps (adder, pad->pad, caps);
|
||||
gst_event_unref (event);
|
||||
|
||||
goto beach;
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_FLUSH_START:
|
||||
res = gst_pad_event_default (pad->pad, GST_OBJECT (adder), event);
|
||||
break;
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
/* we received a flush-stop. The collect_event function will call the
|
||||
* gst_adder_event function we have set on the GstCollectPads2, so we
|
||||
* have control over whether the event is sent past our element.
|
||||
* We will only forward it when flush_stop_pending is set, and we will
|
||||
* unset it then.
|
||||
/* we received a flush-stop. We will only forward it when
|
||||
* flush_stop_pending is set, and we will unset it then.
|
||||
*/
|
||||
GST_COLLECT_PADS2_STREAM_LOCK (adder->collect);
|
||||
g_atomic_int_set (&adder->new_segment_pending, TRUE);
|
||||
if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending,
|
||||
TRUE, FALSE)) {
|
||||
g_atomic_int_set (&adder->new_segment_pending, TRUE);
|
||||
GST_DEBUG_OBJECT (pad->pad, "forwarding flush stop");
|
||||
} else {
|
||||
gst_event_unref (event);
|
||||
res = TRUE;
|
||||
GST_DEBUG_OBJECT (pad->pad, "eating flush stop");
|
||||
}
|
||||
/* Clear pending tags */
|
||||
if (adder->pending_events) {
|
||||
g_list_foreach (adder->pending_events, (GFunc) gst_event_unref, NULL);
|
||||
g_list_free (adder->pending_events);
|
||||
adder->pending_events = NULL;
|
||||
}
|
||||
GST_COLLECT_PADS2_STREAM_UNLOCK (adder->collect);
|
||||
res = gst_pad_event_default (pad->pad, GST_OBJECT (adder), event);
|
||||
break;
|
||||
case GST_EVENT_TAG:
|
||||
GST_COLLECT_PADS2_STREAM_LOCK (adder->collect);
|
||||
/* collect tags here so we can push them out when we collect data */
|
||||
adder->pending_events = g_list_append (adder->pending_events, event);
|
||||
GST_COLLECT_PADS2_STREAM_UNLOCK (adder->collect);
|
||||
goto beach;
|
||||
res = TRUE;
|
||||
break;
|
||||
case GST_EVENT_SEGMENT:
|
||||
if (g_atomic_int_compare_and_exchange (&adder->wait_for_new_segment,
|
||||
TRUE, FALSE)) {
|
||||
|
@ -814,16 +819,19 @@ gst_adder_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
* see FIXME in gst_adder_collected() */
|
||||
g_atomic_int_set (&adder->new_segment_pending, TRUE);
|
||||
}
|
||||
gst_event_unref (event);
|
||||
res = TRUE;
|
||||
break;
|
||||
case GST_EVENT_EOS:
|
||||
gst_event_unref (event);
|
||||
res = TRUE;
|
||||
break;
|
||||
default:
|
||||
res = gst_pad_event_default (pad->pad, GST_OBJECT (adder), event);
|
||||
break;
|
||||
}
|
||||
|
||||
/* now GstCollectPads2 can take care of the rest, e.g. EOS */
|
||||
ret = adder->collect_event (pad, parent, event);
|
||||
|
||||
beach:
|
||||
return ret;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -892,7 +900,7 @@ gst_adder_init (GstAdder * adder)
|
|||
gst_collect_pads2_set_clip_function (adder->collect,
|
||||
GST_DEBUG_FUNCPTR (gst_adder_do_clip), adder);
|
||||
gst_collect_pads2_set_event_function (adder->collect,
|
||||
GST_DEBUG_FUNCPTR (gst_adder_event), adder);
|
||||
GST_DEBUG_FUNCPTR (gst_adder_sink_event), adder);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -992,12 +1000,6 @@ gst_adder_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
|||
gst_pad_set_query_function (newpad, GST_DEBUG_FUNCPTR (gst_adder_sink_query));
|
||||
gst_collect_pads2_add_pad (adder->collect, newpad, sizeof (GstCollectData2));
|
||||
|
||||
/* FIXME: hacked way to override/extend the event function of
|
||||
* GstCollectPads2; because it sets its own event function giving the
|
||||
* element no access to events */
|
||||
adder->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (newpad);
|
||||
gst_pad_set_event_function (newpad, GST_DEBUG_FUNCPTR (gst_adder_sink_event));
|
||||
|
||||
/* takes ownership of the pad */
|
||||
if (!gst_element_add_pad (GST_ELEMENT (adder), newpad))
|
||||
goto could_not_add;
|
||||
|
@ -1218,7 +1220,7 @@ gst_adder_collected (GstCollectPads2 * pads, gpointer user_data)
|
|||
|
||||
if (event) {
|
||||
if (!gst_pad_push_event (adder->srcpad, event)) {
|
||||
GST_WARNING_OBJECT (adder->srcpad, "Sending event failed");
|
||||
GST_WARNING_OBJECT (adder->srcpad, "Sending new segment event failed");
|
||||
}
|
||||
} else {
|
||||
GST_WARNING_OBJECT (adder->srcpad, "Creating new segment event for "
|
||||
|
@ -1292,32 +1294,6 @@ eos:
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_adder_event (GstCollectPads2 * pads, GstCollectData2 * pad,
|
||||
GstEvent * event, gpointer user_data)
|
||||
{
|
||||
GstAdder *adder = GST_ADDER (user_data);
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
||||
if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending,
|
||||
TRUE, FALSE)) {
|
||||
|
||||
return gst_pad_event_default (pad->pad, GST_OBJECT (user_data), event);
|
||||
} else {
|
||||
gst_event_unref (event);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT ||
|
||||
GST_EVENT_TYPE (event) == GST_EVENT_CAPS ||
|
||||
GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
|
||||
gst_event_unref (event);
|
||||
return TRUE;
|
||||
} else {
|
||||
return gst_pad_event_default (pad->pad, GST_OBJECT (user_data), event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_adder_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
|
@ -1359,7 +1335,6 @@ gst_adder_change_state (GstElement * element, GstStateChange transition)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
|
|
|
@ -65,7 +65,6 @@ struct _GstAdder {
|
|||
gint64 offset;
|
||||
|
||||
/* sink event handling */
|
||||
GstPadEventFunction collect_event;
|
||||
GstSegment segment;
|
||||
volatile gboolean new_segment_pending;
|
||||
volatile gboolean wait_for_new_segment;
|
||||
|
|
|
@ -65,6 +65,8 @@ gst_play_flags_get_type (void)
|
|||
"buffering"},
|
||||
{C_FLAGS (GST_PLAY_FLAG_DEINTERLACE), "Deinterlace video if necessary",
|
||||
"deinterlace"},
|
||||
{C_FLAGS (GST_PLAY_FLAG_SOFT_COLORBALANCE), "Use software color balance",
|
||||
"soft-colorbalance"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
static volatile GType id = 0;
|
||||
|
|
|
@ -70,7 +70,8 @@ typedef enum {
|
|||
GST_PLAY_FLAG_NATIVE_VIDEO = (1 << 6),
|
||||
GST_PLAY_FLAG_DOWNLOAD = (1 << 7),
|
||||
GST_PLAY_FLAG_BUFFERING = (1 << 8),
|
||||
GST_PLAY_FLAG_DEINTERLACE = (1 << 9)
|
||||
GST_PLAY_FLAG_DEINTERLACE = (1 << 9),
|
||||
GST_PLAY_FLAG_SOFT_COLORBALANCE = (1 << 10)
|
||||
} GstPlayFlags;
|
||||
|
||||
#define GST_TYPE_PLAY_FLAGS (gst_play_flags_get_type())
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
* <title>Embedding the video window in your application</title>
|
||||
* By default, playbin (or rather the video sinks used) will create their own
|
||||
* window. Applications will usually want to force output to a window of their
|
||||
* own, however. This can be done using the #GstXOverlay interface, which most
|
||||
* own, however. This can be done using the #GstVideoOverlay interface, which most
|
||||
* video sinks implement. See the documentation there for more details.
|
||||
* </refsect2>
|
||||
* <refsect2>
|
||||
|
@ -229,15 +229,15 @@
|
|||
#include <gst/gst-i18n-plugin.h>
|
||||
#include <gst/pbutils/pbutils.h>
|
||||
#include <gst/audio/streamvolume.h>
|
||||
|
||||
#include <gst/video/videooverlay.h>
|
||||
#include <gst/interfaces/navigation.h>
|
||||
#include <gst/video/colorbalance.h>
|
||||
#include "gstplay-enum.h"
|
||||
#include "gstplay-marshal.h"
|
||||
#include "gstplayback.h"
|
||||
#include "gstplaysink.h"
|
||||
#include "gstsubtitleoverlay.h"
|
||||
|
||||
#include "gst/glib-compat-private.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_play_bin_debug);
|
||||
#define GST_CAT_DEFAULT gst_play_bin_debug
|
||||
|
||||
|
@ -458,7 +458,7 @@ struct _GstPlayBinClass
|
|||
#define DEFAULT_SUBURI NULL
|
||||
#define DEFAULT_SOURCE NULL
|
||||
#define DEFAULT_FLAGS GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_TEXT | \
|
||||
GST_PLAY_FLAG_SOFT_VOLUME
|
||||
GST_PLAY_FLAG_SOFT_VOLUME | GST_PLAY_FLAG_SOFT_COLORBALANCE
|
||||
#define DEFAULT_N_VIDEO 0
|
||||
#define DEFAULT_CURRENT_VIDEO -1
|
||||
#define DEFAULT_N_AUDIO 0
|
||||
|
@ -580,6 +580,12 @@ if (id) { \
|
|||
id = 0; \
|
||||
}
|
||||
|
||||
static void gst_play_bin_overlay_init (gpointer g_iface, gpointer g_iface_data);
|
||||
static void gst_play_bin_navigation_init (gpointer g_iface,
|
||||
gpointer g_iface_data);
|
||||
static void gst_play_bin_colorbalance_init (gpointer g_iface,
|
||||
gpointer g_iface_data);
|
||||
|
||||
static GType
|
||||
gst_play_bin_get_type (void)
|
||||
{
|
||||
|
@ -601,12 +607,30 @@ gst_play_bin_get_type (void)
|
|||
static const GInterfaceInfo svol_info = {
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
static const GInterfaceInfo ov_info = {
|
||||
gst_play_bin_overlay_init,
|
||||
NULL, NULL
|
||||
};
|
||||
static const GInterfaceInfo nav_info = {
|
||||
gst_play_bin_navigation_init,
|
||||
NULL, NULL
|
||||
};
|
||||
static const GInterfaceInfo col_info = {
|
||||
gst_play_bin_colorbalance_init,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
gst_play_bin_type = g_type_register_static (GST_TYPE_PIPELINE,
|
||||
"GstPlayBin", &gst_play_bin_info, 0);
|
||||
|
||||
g_type_add_interface_static (gst_play_bin_type, GST_TYPE_STREAM_VOLUME,
|
||||
&svol_info);
|
||||
g_type_add_interface_static (gst_play_bin_type, GST_TYPE_VIDEO_OVERLAY,
|
||||
&ov_info);
|
||||
g_type_add_interface_static (gst_play_bin_type, GST_TYPE_NAVIGATION,
|
||||
&nav_info);
|
||||
g_type_add_interface_static (gst_play_bin_type, GST_TYPE_COLOR_BALANCE,
|
||||
&col_info);
|
||||
}
|
||||
|
||||
return gst_play_bin_type;
|
||||
|
@ -1217,6 +1241,13 @@ notify_mute_cb (GObject * selector, GParamSpec * pspec, GstPlayBin * playbin)
|
|||
g_object_notify (G_OBJECT (playbin), "mute");
|
||||
}
|
||||
|
||||
static void
|
||||
colorbalance_value_changed_cb (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value, GstPlayBin * playbin)
|
||||
{
|
||||
gst_color_balance_value_changed (GST_COLOR_BALANCE (playbin), channel, value);
|
||||
}
|
||||
|
||||
/* Must be called with elements lock! */
|
||||
static void
|
||||
gst_play_bin_update_elements_list (GstPlayBin * playbin)
|
||||
|
@ -1260,7 +1291,8 @@ gst_play_bin_init (GstPlayBin * playbin)
|
|||
g_mutex_init (&playbin->elements_lock);
|
||||
|
||||
/* add sink */
|
||||
playbin->playsink = g_object_new (GST_TYPE_PLAY_SINK, NULL);
|
||||
playbin->playsink =
|
||||
g_object_new (GST_TYPE_PLAY_SINK, "name", "playsink", NULL);
|
||||
gst_bin_add (GST_BIN_CAST (playbin), GST_ELEMENT_CAST (playbin->playsink));
|
||||
gst_play_sink_set_flags (playbin->playsink, DEFAULT_FLAGS);
|
||||
/* Connect to notify::volume and notify::mute signals for proxying */
|
||||
|
@ -1268,6 +1300,8 @@ gst_play_bin_init (GstPlayBin * playbin)
|
|||
G_CALLBACK (notify_volume_cb), playbin);
|
||||
g_signal_connect (playbin->playsink, "notify::mute",
|
||||
G_CALLBACK (notify_mute_cb), playbin);
|
||||
g_signal_connect (playbin->playsink, "value-changed",
|
||||
G_CALLBACK (colorbalance_value_changed_cb), playbin);
|
||||
|
||||
playbin->current_video = DEFAULT_CURRENT_VIDEO;
|
||||
playbin->current_audio = DEFAULT_CURRENT_AUDIO;
|
||||
|
@ -4026,6 +4060,121 @@ failure:
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_overlay_expose (GstVideoOverlay * overlay)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (overlay);
|
||||
|
||||
gst_video_overlay_expose (GST_VIDEO_OVERLAY (playbin->playsink));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_overlay_handle_events (GstVideoOverlay * overlay,
|
||||
gboolean handle_events)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (overlay);
|
||||
|
||||
gst_video_overlay_handle_events (GST_VIDEO_OVERLAY (playbin->playsink),
|
||||
handle_events);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_overlay_set_render_rectangle (GstVideoOverlay * overlay, gint x,
|
||||
gint y, gint width, gint height)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (overlay);
|
||||
|
||||
gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (playbin->playsink),
|
||||
x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_overlay_set_window_handle (GstVideoOverlay * overlay,
|
||||
guintptr handle)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (overlay);
|
||||
|
||||
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (playbin->playsink),
|
||||
handle);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_overlay_init (gpointer g_iface, gpointer g_iface_data)
|
||||
{
|
||||
GstVideoOverlayInterface *iface = (GstVideoOverlayInterface *) g_iface;
|
||||
iface->expose = gst_play_bin_overlay_expose;
|
||||
iface->handle_events = gst_play_bin_overlay_handle_events;
|
||||
iface->set_render_rectangle = gst_play_bin_overlay_set_render_rectangle;
|
||||
iface->set_window_handle = gst_play_bin_overlay_set_window_handle;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_navigation_send_event (GstNavigation * navigation,
|
||||
GstStructure * structure)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (navigation);
|
||||
|
||||
gst_navigation_send_event (GST_NAVIGATION (playbin->playsink), structure);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_navigation_init (gpointer g_iface, gpointer g_iface_data)
|
||||
{
|
||||
GstNavigationInterface *iface = (GstNavigationInterface *) g_iface;
|
||||
|
||||
iface->send_event = gst_play_bin_navigation_send_event;
|
||||
}
|
||||
|
||||
static const GList *
|
||||
gst_play_bin_colorbalance_list_channels (GstColorBalance * balance)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (balance);
|
||||
|
||||
return
|
||||
gst_color_balance_list_channels (GST_COLOR_BALANCE (playbin->playsink));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_colorbalance_set_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (balance);
|
||||
|
||||
gst_color_balance_set_value (GST_COLOR_BALANCE (playbin->playsink), channel,
|
||||
value);
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_play_bin_colorbalance_get_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (balance);
|
||||
|
||||
return gst_color_balance_get_value (GST_COLOR_BALANCE (playbin->playsink),
|
||||
channel);
|
||||
}
|
||||
|
||||
static GstColorBalanceType
|
||||
gst_play_bin_colorbalance_get_balance_type (GstColorBalance * balance)
|
||||
{
|
||||
GstPlayBin *playbin = GST_PLAY_BIN (balance);
|
||||
|
||||
return
|
||||
gst_color_balance_get_balance_type (GST_COLOR_BALANCE
|
||||
(playbin->playsink));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_colorbalance_init (gpointer g_iface, gpointer g_iface_data)
|
||||
{
|
||||
GstColorBalanceInterface *iface = (GstColorBalanceInterface *) g_iface;
|
||||
|
||||
iface->list_channels = gst_play_bin_colorbalance_list_channels;
|
||||
iface->set_value = gst_play_bin_colorbalance_set_value;
|
||||
iface->get_value = gst_play_bin_colorbalance_get_value;
|
||||
iface->get_balance_type = gst_play_bin_colorbalance_get_balance_type;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_play_bin2_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
#include <gst/gst-i18n-plugin.h>
|
||||
#include <gst/pbutils/pbutils.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/audio/streamvolume.h>
|
||||
#include <gst/video/colorbalance.h>
|
||||
#include <gst/video/videooverlay.h>
|
||||
#include <gst/interfaces/navigation.h>
|
||||
|
||||
#include "gstplaysink.h"
|
||||
#include "gststreamsynchronizer.h"
|
||||
|
@ -40,7 +44,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_play_sink_debug);
|
|||
#define VOLUME_MAX_DOUBLE 10.0
|
||||
|
||||
#define DEFAULT_FLAGS GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_TEXT | \
|
||||
GST_PLAY_FLAG_SOFT_VOLUME
|
||||
GST_PLAY_FLAG_SOFT_VOLUME | GST_PLAY_FLAG_SOFT_COLORBALANCE
|
||||
|
||||
#define GST_PLAY_CHAIN(c) ((GstPlayChain *)(c))
|
||||
|
||||
|
@ -202,6 +206,20 @@ struct _GstPlaySink
|
|||
gboolean volume_changed; /* volume/mute changed while no audiochain */
|
||||
gboolean mute_changed; /* ... has been created yet */
|
||||
gint64 av_offset;
|
||||
|
||||
/* videooverlay proxy interface */
|
||||
GstVideoOverlay *overlay_element; /* protected with LOCK */
|
||||
gboolean overlay_handle_set;
|
||||
guintptr overlay_handle;
|
||||
gboolean overlay_render_rectangle_set;
|
||||
gint overlay_x, overlay_y, overlay_width, overlay_height;
|
||||
gboolean overlay_handle_events_set;
|
||||
gboolean overlay_handle_events;
|
||||
|
||||
/* colorbalance proxy interface */
|
||||
GstColorBalance *colorbalance_element;
|
||||
GList *colorbalance_channels; /* CONTRAST, BRIGHTNESS, HUE, SATURATION */
|
||||
gint colorbalance_values[4];
|
||||
};
|
||||
|
||||
struct _GstPlaySinkClass
|
||||
|
@ -324,7 +342,40 @@ gst_play_marshal_SAMPLE__BOXED (GClosure * closure,
|
|||
|
||||
/* static guint gst_play_sink_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
G_DEFINE_TYPE (GstPlaySink, gst_play_sink, GST_TYPE_BIN);
|
||||
static void gst_play_sink_overlay_init (gpointer g_iface,
|
||||
gpointer g_iface_data);
|
||||
static void gst_play_sink_navigation_init (gpointer g_iface,
|
||||
gpointer g_iface_data);
|
||||
static void gst_play_sink_colorbalance_init (gpointer g_iface,
|
||||
gpointer g_iface_data);
|
||||
|
||||
static void
|
||||
_do_init (GType type)
|
||||
{
|
||||
static const GInterfaceInfo svol_info = {
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
static const GInterfaceInfo ov_info = {
|
||||
gst_play_sink_overlay_init,
|
||||
NULL, NULL
|
||||
};
|
||||
static const GInterfaceInfo nav_info = {
|
||||
gst_play_sink_navigation_init,
|
||||
NULL, NULL
|
||||
};
|
||||
static const GInterfaceInfo col_info = {
|
||||
gst_play_sink_colorbalance_init,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
g_type_add_interface_static (type, GST_TYPE_STREAM_VOLUME, &svol_info);
|
||||
g_type_add_interface_static (type, GST_TYPE_VIDEO_OVERLAY, &ov_info);
|
||||
g_type_add_interface_static (type, GST_TYPE_NAVIGATION, &nav_info);
|
||||
g_type_add_interface_static (type, GST_TYPE_COLOR_BALANCE, &col_info);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GstPlaySink, gst_play_sink, GST_TYPE_BIN,
|
||||
_do_init (g_define_type_id));
|
||||
|
||||
static void
|
||||
gst_play_sink_class_init (GstPlaySinkClass * klass)
|
||||
|
@ -434,6 +485,7 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
|
|||
g_param_spec_object ("audio-sink", "Audio Sink",
|
||||
"the audio output element to use (NULL = default sink)",
|
||||
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstPlaySink:text-sink:
|
||||
*
|
||||
|
@ -505,6 +557,8 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
|
|||
static void
|
||||
gst_play_sink_init (GstPlaySink * playsink)
|
||||
{
|
||||
GstColorBalanceChannel *channel;
|
||||
|
||||
/* init groups */
|
||||
playsink->video_sink = NULL;
|
||||
playsink->audio_sink = NULL;
|
||||
|
@ -522,6 +576,46 @@ gst_play_sink_init (GstPlaySink * playsink)
|
|||
|
||||
g_rec_mutex_init (&playsink->lock);
|
||||
GST_OBJECT_FLAG_SET (playsink, GST_ELEMENT_FLAG_SINK);
|
||||
|
||||
channel =
|
||||
GST_COLOR_BALANCE_CHANNEL (g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL,
|
||||
NULL));
|
||||
channel->label = g_strdup ("CONTRAST");
|
||||
channel->min_value = -1000;
|
||||
channel->max_value = 1000;
|
||||
playsink->colorbalance_channels =
|
||||
g_list_append (playsink->colorbalance_channels, channel);
|
||||
playsink->colorbalance_values[0] = 0;
|
||||
|
||||
channel =
|
||||
GST_COLOR_BALANCE_CHANNEL (g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL,
|
||||
NULL));
|
||||
channel->label = g_strdup ("BRIGHTNESS");
|
||||
channel->min_value = -1000;
|
||||
channel->max_value = 1000;
|
||||
playsink->colorbalance_channels =
|
||||
g_list_append (playsink->colorbalance_channels, channel);
|
||||
playsink->colorbalance_values[1] = 0;
|
||||
|
||||
channel =
|
||||
GST_COLOR_BALANCE_CHANNEL (g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL,
|
||||
NULL));
|
||||
channel->label = g_strdup ("HUE");
|
||||
channel->min_value = -1000;
|
||||
channel->max_value = 1000;
|
||||
playsink->colorbalance_channels =
|
||||
g_list_append (playsink->colorbalance_channels, channel);
|
||||
playsink->colorbalance_values[2] = 0;
|
||||
|
||||
channel =
|
||||
GST_COLOR_BALANCE_CHANNEL (g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL,
|
||||
NULL));
|
||||
channel->label = g_strdup ("SATURATION");
|
||||
channel->min_value = -1000;
|
||||
channel->max_value = 1000;
|
||||
playsink->colorbalance_channels =
|
||||
g_list_append (playsink->colorbalance_channels, channel);
|
||||
playsink->colorbalance_values[3] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -613,6 +707,11 @@ gst_play_sink_dispose (GObject * object)
|
|||
|
||||
playsink->stream_synchronizer = NULL;
|
||||
|
||||
g_list_foreach (playsink->colorbalance_channels, (GFunc) gst_object_unref,
|
||||
NULL);
|
||||
g_list_free (playsink->colorbalance_channels);
|
||||
playsink->colorbalance_channels = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gst_play_sink_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
@ -1231,6 +1330,149 @@ link_failed:
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_valid_color_balance_element (GstColorBalance * bal)
|
||||
{
|
||||
gboolean have_brightness = FALSE;
|
||||
gboolean have_contrast = FALSE;
|
||||
gboolean have_hue = FALSE;
|
||||
gboolean have_saturation = FALSE;
|
||||
const GList *channels, *l;
|
||||
|
||||
channels = gst_color_balance_list_channels (bal);
|
||||
for (l = channels; l; l = l->next) {
|
||||
GstColorBalanceChannel *ch = l->data;
|
||||
|
||||
if (g_strrstr (ch->label, "BRIGHTNESS"))
|
||||
have_brightness = TRUE;
|
||||
else if (g_strrstr (ch->label, "CONTRAST"))
|
||||
have_contrast = TRUE;
|
||||
else if (g_strrstr (ch->label, "HUE"))
|
||||
have_hue = TRUE;
|
||||
else if (g_strrstr (ch->label, "SATURATION"))
|
||||
have_saturation = TRUE;
|
||||
}
|
||||
|
||||
return have_brightness && have_contrast && have_hue && have_saturation;
|
||||
}
|
||||
|
||||
static void
|
||||
iterate_color_balance_elements (const GValue * item, gpointer user_data)
|
||||
{
|
||||
gboolean valid;
|
||||
GstColorBalance *cb, **cb_out = user_data;
|
||||
|
||||
cb = GST_COLOR_BALANCE (g_value_get_object (item));
|
||||
valid = is_valid_color_balance_element (cb);
|
||||
if (valid) {
|
||||
if (*cb_out
|
||||
&& gst_color_balance_get_balance_type (*cb_out) ==
|
||||
GST_COLOR_BALANCE_SOFTWARE) {
|
||||
gst_object_unref (*cb_out);
|
||||
*cb_out = GST_COLOR_BALANCE (gst_object_ref (cb));
|
||||
} else if (!*cb_out) {
|
||||
*cb_out = GST_COLOR_BALANCE (gst_object_ref (cb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GstColorBalance *
|
||||
find_color_balance_element (GstElement * element)
|
||||
{
|
||||
GstIterator *it;
|
||||
GstColorBalance *cb = NULL;
|
||||
|
||||
if (GST_IS_COLOR_BALANCE (element)
|
||||
&& is_valid_color_balance_element (GST_COLOR_BALANCE (element)))
|
||||
return GST_COLOR_BALANCE (gst_object_ref (element));
|
||||
else if (!GST_IS_BIN (element))
|
||||
return FALSE;
|
||||
|
||||
it = gst_bin_iterate_all_by_interface (GST_BIN (element),
|
||||
GST_TYPE_COLOR_BALANCE);
|
||||
while (gst_iterator_foreach (it, iterate_color_balance_elements,
|
||||
&cb) == GST_ITERATOR_RESYNC)
|
||||
gst_iterator_resync (it);
|
||||
gst_iterator_free (it);
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
static void
|
||||
colorbalance_value_changed_cb (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value, GstPlaySink * playsink)
|
||||
{
|
||||
GList *l;
|
||||
gint i;
|
||||
|
||||
for (i = 0, l = playsink->colorbalance_channels; l; l = l->next, i++) {
|
||||
GstColorBalanceChannel *proxy = l->data;
|
||||
|
||||
if (g_strrstr (channel->label, proxy->label)) {
|
||||
gdouble new_val;
|
||||
|
||||
/* Convert to [0, 1] range */
|
||||
new_val =
|
||||
((gdouble) value -
|
||||
(gdouble) channel->min_value) / ((gdouble) channel->max_value -
|
||||
(gdouble) channel->min_value);
|
||||
/* Convert to proxy range */
|
||||
new_val =
|
||||
proxy->min_value + new_val * ((gdouble) proxy->max_value -
|
||||
(gdouble) proxy->min_value);
|
||||
playsink->colorbalance_values[i] = (gint) (0.5 + new_val);
|
||||
|
||||
gst_color_balance_value_changed (GST_COLOR_BALANCE (playsink), proxy,
|
||||
playsink->colorbalance_values[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_colorbalance (GstPlaySink * playsink)
|
||||
{
|
||||
GstColorBalance *balance = NULL;
|
||||
GList *l;
|
||||
gint i;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->colorbalance_element) {
|
||||
balance =
|
||||
GST_COLOR_BALANCE (gst_object_ref (playsink->colorbalance_element));
|
||||
}
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
if (!balance)
|
||||
return;
|
||||
|
||||
g_signal_handlers_block_by_func (balance,
|
||||
G_CALLBACK (colorbalance_value_changed_cb), playsink);
|
||||
|
||||
for (i = 0, l = playsink->colorbalance_channels; l; l = l->next, i++) {
|
||||
GstColorBalanceChannel *proxy = l->data;
|
||||
GstColorBalanceChannel *channel = NULL;
|
||||
const GList *channels, *k;
|
||||
|
||||
channels = gst_color_balance_list_channels (balance);
|
||||
for (k = channels; k; k = k->next) {
|
||||
GstColorBalanceChannel *tmp = k->data;
|
||||
|
||||
if (g_strrstr (tmp->label, proxy->label)) {
|
||||
channel = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (channel);
|
||||
|
||||
gst_color_balance_set_value (balance, channel,
|
||||
playsink->colorbalance_values[i]);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (balance,
|
||||
G_CALLBACK (colorbalance_value_changed_cb), playsink);
|
||||
}
|
||||
|
||||
/* make the element (bin) that contains the elements needed to perform
|
||||
* video display.
|
||||
*
|
||||
|
@ -1298,6 +1540,13 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
|||
chain->async = TRUE;
|
||||
}
|
||||
|
||||
/* Make sure the aspect ratio is kept */
|
||||
elem =
|
||||
gst_play_sink_find_property_sinks (playsink, chain->sink,
|
||||
"force-aspect-ratio", G_TYPE_BOOLEAN);
|
||||
if (elem)
|
||||
g_object_set (elem, "force-aspect-ratio", TRUE, NULL);
|
||||
|
||||
/* find ts-offset element */
|
||||
gst_object_replace ((GstObject **) & chain->ts_offset, (GstObject *)
|
||||
gst_play_sink_find_property_sinks (playsink, chain->sink, "ts-offset",
|
||||
|
@ -1310,6 +1559,34 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
|||
gst_object_ref_sink (bin);
|
||||
gst_bin_add (bin, chain->sink);
|
||||
|
||||
/* Get the VideoOverlay element */
|
||||
{
|
||||
GstVideoOverlay *overlay = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
gst_object_unref (playsink->overlay_element);
|
||||
playsink->overlay_element =
|
||||
GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (chain->chain.bin),
|
||||
GST_TYPE_VIDEO_OVERLAY));
|
||||
if (playsink->overlay_element)
|
||||
overlay = GST_VIDEO_OVERLAY (gst_object_ref (playsink->overlay_element));
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
if (overlay) {
|
||||
if (playsink->overlay_handle_set)
|
||||
gst_video_overlay_set_window_handle (overlay, playsink->overlay_handle);
|
||||
if (playsink->overlay_handle_events_set)
|
||||
gst_video_overlay_handle_events (overlay,
|
||||
playsink->overlay_handle_events);
|
||||
if (playsink->overlay_render_rectangle_set)
|
||||
gst_video_overlay_set_render_rectangle (overlay,
|
||||
playsink->overlay_x, playsink->overlay_y,
|
||||
playsink->overlay_width, playsink->overlay_height);
|
||||
gst_object_unref (overlay);
|
||||
}
|
||||
}
|
||||
|
||||
/* decouple decoder from sink, this improves playback quite a lot since the
|
||||
* decoder can continue while the sink blocks for synchronisation. We don't
|
||||
* need a lot of buffers as this consumes a lot of memory and we don't want
|
||||
|
@ -1329,10 +1606,34 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
|||
head = prev = chain->queue;
|
||||
}
|
||||
|
||||
if (!(playsink->flags & GST_PLAY_FLAG_NATIVE_VIDEO)) {
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->colorbalance_element) {
|
||||
g_signal_handlers_disconnect_by_func (playsink->colorbalance_element,
|
||||
G_CALLBACK (colorbalance_value_changed_cb), playsink);
|
||||
gst_object_unref (playsink->colorbalance_element);
|
||||
}
|
||||
playsink->colorbalance_element = find_color_balance_element (chain->sink);
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
if (!(playsink->flags & GST_PLAY_FLAG_NATIVE_VIDEO)
|
||||
|| (!playsink->colorbalance_element
|
||||
&& (playsink->flags & GST_PLAY_FLAG_SOFT_COLORBALANCE))) {
|
||||
gboolean use_converters = !(playsink->flags & GST_PLAY_FLAG_NATIVE_VIDEO);
|
||||
gboolean use_balance = !playsink->colorbalance_element
|
||||
&& (playsink->flags & GST_PLAY_FLAG_SOFT_COLORBALANCE);
|
||||
|
||||
GST_DEBUG_OBJECT (playsink, "creating videoconverter");
|
||||
chain->conv =
|
||||
g_object_new (GST_TYPE_PLAY_SINK_VIDEO_CONVERT, "name", "vconv", NULL);
|
||||
g_object_new (GST_TYPE_PLAY_SINK_VIDEO_CONVERT, "name", "vconv",
|
||||
"use-converters", use_converters, "use-balance", use_balance, NULL);
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (use_balance && GST_PLAY_SINK_VIDEO_CONVERT (chain->conv)->balance)
|
||||
playsink->colorbalance_element =
|
||||
GST_COLOR_BALANCE (gst_object_ref (GST_PLAY_SINK_VIDEO_CONVERT
|
||||
(chain->conv)->balance));
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
gst_bin_add (bin, chain->conv);
|
||||
if (prev) {
|
||||
if (!gst_element_link_pads_full (prev, "src", chain->conv, "sink",
|
||||
|
@ -1344,6 +1645,8 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
|||
prev = chain->conv;
|
||||
}
|
||||
|
||||
update_colorbalance (playsink);
|
||||
|
||||
if (prev) {
|
||||
GST_DEBUG_OBJECT (playsink, "linking to sink");
|
||||
if (!gst_element_link_pads_full (prev, "src", chain->sink, NULL,
|
||||
|
@ -1390,6 +1693,7 @@ no_sinks:
|
|||
free_chain ((GstPlayChain *) chain);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
link_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (playsink, CORE, PAD,
|
||||
|
@ -1423,8 +1727,35 @@ setup_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
|||
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
return FALSE;
|
||||
|
||||
/* find ts-offset element */
|
||||
/* Get the VideoOverlay element */
|
||||
{
|
||||
GstVideoOverlay *overlay = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
gst_object_unref (playsink->overlay_element);
|
||||
playsink->overlay_element =
|
||||
GST_VIDEO_OVERLAY (gst_bin_get_by_interface (GST_BIN (chain->chain.bin),
|
||||
GST_TYPE_VIDEO_OVERLAY));
|
||||
if (playsink->overlay_element)
|
||||
overlay = GST_VIDEO_OVERLAY (gst_object_ref (playsink->overlay_element));
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
if (overlay) {
|
||||
if (playsink->overlay_handle_set)
|
||||
gst_video_overlay_set_window_handle (overlay, playsink->overlay_handle);
|
||||
if (playsink->overlay_handle_events_set)
|
||||
gst_video_overlay_handle_events (overlay,
|
||||
playsink->overlay_handle_events);
|
||||
if (playsink->overlay_render_rectangle_set)
|
||||
gst_video_overlay_set_render_rectangle (overlay,
|
||||
playsink->overlay_x, playsink->overlay_y,
|
||||
playsink->overlay_width, playsink->overlay_height);
|
||||
gst_object_unref (overlay);
|
||||
}
|
||||
}
|
||||
|
||||
/* find ts-offset element */
|
||||
gst_object_replace ((GstObject **) & chain->ts_offset, (GstObject *)
|
||||
gst_play_sink_find_property_sinks (playsink, chain->sink, "ts-offset",
|
||||
G_TYPE_INT64));
|
||||
|
@ -1443,6 +1774,39 @@ setup_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
|||
GST_DEBUG_OBJECT (playsink, "no async property on the sink");
|
||||
chain->async = TRUE;
|
||||
}
|
||||
|
||||
/* Make sure the aspect ratio is kept */
|
||||
elem =
|
||||
gst_play_sink_find_property_sinks (playsink, chain->sink,
|
||||
"force-aspect-ratio", G_TYPE_BOOLEAN);
|
||||
if (elem)
|
||||
g_object_set (elem, "force-aspect-ratio", TRUE, NULL);
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->colorbalance_element) {
|
||||
g_signal_handlers_disconnect_by_func (playsink->colorbalance_element,
|
||||
G_CALLBACK (colorbalance_value_changed_cb), playsink);
|
||||
gst_object_unref (playsink->colorbalance_element);
|
||||
}
|
||||
playsink->colorbalance_element = find_color_balance_element (chain->sink);
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
if (chain->conv) {
|
||||
gboolean use_balance = !playsink->colorbalance_element
|
||||
&& (playsink->flags & GST_PLAY_FLAG_SOFT_COLORBALANCE);
|
||||
|
||||
g_object_set (chain->conv, "use-balance", use_balance, NULL);
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (use_balance && GST_PLAY_SINK_VIDEO_CONVERT (chain->conv)->balance)
|
||||
playsink->colorbalance_element =
|
||||
GST_COLOR_BALANCE (gst_object_ref (GST_PLAY_SINK_VIDEO_CONVERT
|
||||
(chain->conv)->balance));
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
}
|
||||
|
||||
update_colorbalance (playsink);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1801,10 +2165,10 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw)
|
|||
}
|
||||
|
||||
if (!(playsink->flags & GST_PLAY_FLAG_NATIVE_AUDIO) || (!have_volume
|
||||
&& playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME)) {
|
||||
&& (playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME))) {
|
||||
gboolean use_converters = !(playsink->flags & GST_PLAY_FLAG_NATIVE_AUDIO);
|
||||
gboolean use_volume =
|
||||
!have_volume && playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME;
|
||||
!have_volume && (playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME);
|
||||
GST_DEBUG_OBJECT (playsink,
|
||||
"creating audioconvert with use-converters %d, use-volume %d",
|
||||
use_converters, use_volume);
|
||||
|
@ -1821,7 +2185,7 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw)
|
|||
}
|
||||
prev = chain->conv;
|
||||
|
||||
if (!have_volume && playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME) {
|
||||
if (!have_volume && (playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME)) {
|
||||
GstPlaySinkAudioConvert *conv =
|
||||
GST_PLAY_SINK_AUDIO_CONVERT_CAST (chain->conv);
|
||||
|
||||
|
@ -1974,13 +2338,14 @@ setup_audio_chain (GstPlaySink * playsink, gboolean raw)
|
|||
GST_PLAY_SINK_AUDIO_CONVERT_CAST (chain->conv);
|
||||
|
||||
/* no volume, we need to add a volume element when we can */
|
||||
g_object_set (chain->conv, "use-volume", TRUE, NULL);
|
||||
g_object_set (chain->conv, "use-volume",
|
||||
! !(playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME), NULL);
|
||||
GST_DEBUG_OBJECT (playsink, "the sink has no volume property");
|
||||
|
||||
/* Disconnect signals */
|
||||
disconnect_chain (chain, playsink);
|
||||
|
||||
if (conv->volume) {
|
||||
if (conv->volume && (playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME)) {
|
||||
chain->volume = conv->volume;
|
||||
chain->mute = chain->volume;
|
||||
|
||||
|
@ -2164,6 +2529,19 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
|||
need_text = TRUE;
|
||||
}
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
gst_object_unref (playsink->overlay_element);
|
||||
playsink->overlay_element = NULL;
|
||||
|
||||
if (playsink->colorbalance_element) {
|
||||
g_signal_handlers_disconnect_by_func (playsink->colorbalance_element,
|
||||
G_CALLBACK (colorbalance_value_changed_cb), playsink);
|
||||
gst_object_unref (playsink->colorbalance_element);
|
||||
}
|
||||
playsink->colorbalance_element = NULL;
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
if (((flags & GST_PLAY_FLAG_VIDEO)
|
||||
|| (flags & GST_PLAY_FLAG_NATIVE_VIDEO)) && playsink->video_pad) {
|
||||
/* we have video and we are requested to show it */
|
||||
|
@ -3355,6 +3733,44 @@ gst_play_sink_handle_message (GstBin * bin, GstMessage * message)
|
|||
GST_BIN_CLASS (gst_play_sink_parent_class)->handle_message (bin, message);
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_ELEMENT:{
|
||||
if (gst_is_video_overlay_prepare_window_handle_message (message)) {
|
||||
GstVideoOverlay *overlay;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element
|
||||
&& GST_OBJECT_CAST (playsink->overlay_element) !=
|
||||
GST_MESSAGE_SRC (message)) {
|
||||
gst_object_unref (playsink->overlay_element);
|
||||
playsink->overlay_element = NULL;
|
||||
}
|
||||
|
||||
if (!playsink->overlay_element)
|
||||
playsink->overlay_element =
|
||||
GST_VIDEO_OVERLAY (gst_object_ref (GST_MESSAGE_SRC (message)));
|
||||
overlay =
|
||||
GST_VIDEO_OVERLAY (gst_object_ref (playsink->overlay_element));
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
GST_DEBUG_OBJECT (playsink, "Got prepare-xwindow-id message");
|
||||
|
||||
if (playsink->overlay_handle_set)
|
||||
gst_video_overlay_set_window_handle (playsink->overlay_element,
|
||||
playsink->overlay_handle);
|
||||
if (playsink->overlay_handle_events_set)
|
||||
gst_video_overlay_handle_events (playsink->overlay_element,
|
||||
playsink->overlay_handle_events);
|
||||
if (playsink->overlay_render_rectangle_set)
|
||||
gst_video_overlay_set_render_rectangle (playsink->overlay_element,
|
||||
playsink->overlay_x, playsink->overlay_y,
|
||||
playsink->overlay_width, playsink->overlay_height);
|
||||
|
||||
gst_object_unref (overlay);
|
||||
gst_message_unref (message);
|
||||
gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (playsink));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GST_BIN_CLASS (gst_play_sink_parent_class)->handle_message (bin, message);
|
||||
break;
|
||||
|
@ -3370,7 +3786,6 @@ static gboolean
|
|||
gst_play_sink_send_event_to_sink (GstPlaySink * playsink, GstEvent * event)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
|
||||
if (playsink->textchain && playsink->textchain->sink) {
|
||||
gst_event_ref (event);
|
||||
if ((res = gst_element_send_event (playsink->textchain->chain.bin, event))) {
|
||||
|
@ -3411,9 +3826,7 @@ gst_play_sink_send_event (GstElement * element, GstEvent * event)
|
|||
gboolean res = FALSE;
|
||||
GstEventType event_type = GST_EVENT_TYPE (event);
|
||||
GstPlaySink *playsink;
|
||||
|
||||
playsink = GST_PLAY_SINK_CAST (element);
|
||||
|
||||
switch (event_type) {
|
||||
case GST_EVENT_SEEK:
|
||||
GST_DEBUG_OBJECT (element, "Sending event to a sink");
|
||||
|
@ -3425,10 +3838,8 @@ gst_play_sink_send_event (GstElement * element, GstEvent * event)
|
|||
guint64 amount;
|
||||
gdouble rate;
|
||||
gboolean flush, intermediate;
|
||||
|
||||
gst_event_parse_step (event, &format, &amount, &rate, &flush,
|
||||
&intermediate);
|
||||
|
||||
if (format == GST_FORMAT_BUFFERS) {
|
||||
/* for buffers, we will try to step video frames, for other formats we
|
||||
* send the step to all sinks */
|
||||
|
@ -3454,11 +3865,8 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
{
|
||||
GstStateChangeReturn ret;
|
||||
GstStateChangeReturn bret;
|
||||
|
||||
GstPlaySink *playsink;
|
||||
|
||||
playsink = GST_PLAY_SINK (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
playsink->need_async_start = TRUE;
|
||||
|
@ -3493,6 +3901,20 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
gst_object_unref (playsink->videochain->ts_offset);
|
||||
playsink->videochain->ts_offset = NULL;
|
||||
}
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
gst_object_unref (playsink->overlay_element);
|
||||
playsink->overlay_element = NULL;
|
||||
|
||||
if (playsink->colorbalance_element) {
|
||||
g_signal_handlers_disconnect_by_func (playsink->colorbalance_element,
|
||||
G_CALLBACK (colorbalance_value_changed_cb), playsink);
|
||||
gst_object_unref (playsink->colorbalance_element);
|
||||
}
|
||||
playsink->colorbalance_element = NULL;
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
ret = GST_STATE_CHANGE_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
|
@ -3602,7 +4024,6 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
if (playsink->textchain && playsink->textchain->sink)
|
||||
gst_bin_remove (GST_BIN_CAST (playsink->textchain->chain.bin),
|
||||
playsink->textchain->sink);
|
||||
|
||||
if (playsink->audio_sink != NULL)
|
||||
gst_element_set_state (playsink->audio_sink, GST_STATE_NULL);
|
||||
if (playsink->video_sink != NULL)
|
||||
|
@ -3611,7 +4032,6 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
gst_element_set_state (playsink->visualisation, GST_STATE_NULL);
|
||||
if (playsink->text_sink != NULL)
|
||||
gst_element_set_state (playsink->text_sink, GST_STATE_NULL);
|
||||
|
||||
free_chain ((GstPlayChain *) playsink->videodeinterlacechain);
|
||||
playsink->videodeinterlacechain = NULL;
|
||||
free_chain ((GstPlayChain *) playsink->videochain);
|
||||
|
@ -3628,7 +4048,6 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
break;
|
||||
}
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
activate_failed:
|
||||
{
|
||||
|
@ -3643,7 +4062,6 @@ gst_play_sink_set_property (GObject * object, guint prop_id,
|
|||
const GValue * value, GParamSpec * spec)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FLAGS:
|
||||
gst_play_sink_set_flags (playsink, g_value_get_flags (value));
|
||||
|
@ -3690,7 +4108,6 @@ gst_play_sink_get_property (GObject * object, guint prop_id,
|
|||
GValue * value, GParamSpec * spec)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FLAGS:
|
||||
g_value_set_flags (value, gst_play_sink_get_flags (playsink));
|
||||
|
@ -3735,12 +4152,273 @@ gst_play_sink_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_overlay_expose (GstVideoOverlay * overlay)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (overlay);
|
||||
GstVideoOverlay *overlay_element;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
overlay_element =
|
||||
GST_VIDEO_OVERLAY (gst_object_ref (playsink->overlay_element));
|
||||
else
|
||||
overlay_element = NULL;
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
if (overlay_element) {
|
||||
gst_video_overlay_expose (overlay_element);
|
||||
gst_object_unref (overlay_element);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_overlay_handle_events (GstVideoOverlay * overlay,
|
||||
gboolean handle_events)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (overlay);
|
||||
GstVideoOverlay *overlay_element;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
overlay_element =
|
||||
GST_VIDEO_OVERLAY (gst_object_ref (playsink->overlay_element));
|
||||
else
|
||||
overlay_element = NULL;
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
playsink->overlay_handle_events_set = TRUE;
|
||||
playsink->overlay_handle_events = handle_events;
|
||||
|
||||
if (overlay_element) {
|
||||
gst_video_overlay_handle_events (overlay_element, handle_events);
|
||||
gst_object_unref (overlay_element);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_overlay_set_render_rectangle (GstVideoOverlay * overlay, gint x,
|
||||
gint y, gint width, gint height)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (overlay);
|
||||
GstVideoOverlay *overlay_element;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
overlay_element =
|
||||
GST_VIDEO_OVERLAY (gst_object_ref (playsink->overlay_element));
|
||||
else
|
||||
overlay_element = NULL;
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
playsink->overlay_render_rectangle_set = TRUE;
|
||||
playsink->overlay_x = x;
|
||||
playsink->overlay_y = y;
|
||||
playsink->overlay_width = width;
|
||||
playsink->overlay_height = height;
|
||||
|
||||
if (overlay_element) {
|
||||
gst_video_overlay_set_render_rectangle (overlay_element, x, y, width,
|
||||
height);
|
||||
gst_object_unref (overlay_element);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_overlay_set_window_handle (GstVideoOverlay * overlay,
|
||||
guintptr handle)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (overlay);
|
||||
GstVideoOverlay *overlay_element;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->overlay_element)
|
||||
overlay_element =
|
||||
GST_VIDEO_OVERLAY (gst_object_ref (playsink->overlay_element));
|
||||
else
|
||||
overlay_element = NULL;
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
playsink->overlay_handle_set = TRUE;
|
||||
playsink->overlay_handle = handle;
|
||||
|
||||
if (overlay_element) {
|
||||
gst_video_overlay_set_window_handle (overlay_element, handle);
|
||||
gst_object_unref (overlay_element);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_overlay_init (gpointer g_iface, gpointer g_iface_data)
|
||||
{
|
||||
GstVideoOverlayInterface *iface = (GstVideoOverlayInterface *) g_iface;
|
||||
iface->expose = gst_play_sink_overlay_expose;
|
||||
iface->handle_events = gst_play_sink_overlay_handle_events;
|
||||
iface->set_render_rectangle = gst_play_sink_overlay_set_render_rectangle;
|
||||
iface->set_window_handle = gst_play_sink_overlay_set_window_handle;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_navigation_send_event (GstNavigation * navigation,
|
||||
GstStructure * structure)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (navigation);
|
||||
GstBin *bin = NULL;
|
||||
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
if (playsink->videochain && playsink->videochain->chain.bin)
|
||||
bin = GST_BIN (gst_object_ref (playsink->videochain->chain.bin));
|
||||
GST_PLAY_SINK_UNLOCK (playsink);
|
||||
|
||||
if (bin) {
|
||||
GstElement *nav = gst_bin_get_by_interface (bin, GST_TYPE_NAVIGATION);
|
||||
|
||||
if (nav) {
|
||||
gst_navigation_send_event (GST_NAVIGATION (nav), structure);
|
||||
structure = NULL;
|
||||
gst_object_unref (nav);
|
||||
}
|
||||
|
||||
gst_object_unref (bin);
|
||||
}
|
||||
|
||||
if (structure)
|
||||
gst_structure_free (structure);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_navigation_init (gpointer g_iface, gpointer g_iface_data)
|
||||
{
|
||||
GstNavigationInterface *iface = (GstNavigationInterface *) g_iface;
|
||||
|
||||
iface->send_event = gst_play_sink_navigation_send_event;
|
||||
}
|
||||
|
||||
static const GList *
|
||||
gst_play_sink_colorbalance_list_channels (GstColorBalance * balance)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (balance);
|
||||
|
||||
return playsink->colorbalance_channels;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_colorbalance_set_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * proxy, gint value)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (balance);
|
||||
GList *l;
|
||||
gint i;
|
||||
GstColorBalance *balance_element = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->colorbalance_element)
|
||||
balance_element =
|
||||
GST_COLOR_BALANCE (gst_object_ref (playsink->colorbalance_element));
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
for (i = 0, l = playsink->colorbalance_channels; l; l = l->next, i++) {
|
||||
GstColorBalanceChannel *proxy_tmp = l->data;
|
||||
gdouble new_val;
|
||||
|
||||
if (proxy_tmp != proxy)
|
||||
continue;
|
||||
|
||||
playsink->colorbalance_values[i] = value;
|
||||
|
||||
if (balance_element) {
|
||||
GstColorBalanceChannel *channel = NULL;
|
||||
const GList *channels, *k;
|
||||
|
||||
channels = gst_color_balance_list_channels (balance_element);
|
||||
for (k = channels; k; k = k->next) {
|
||||
GstColorBalanceChannel *tmp = l->data;
|
||||
|
||||
if (g_strrstr (tmp->label, proxy->label)) {
|
||||
channel = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (channel);
|
||||
|
||||
/* Convert to [0, 1] range */
|
||||
new_val =
|
||||
((gdouble) value -
|
||||
(gdouble) proxy->min_value) / ((gdouble) proxy->max_value -
|
||||
(gdouble) proxy->min_value);
|
||||
/* Convert to channel range */
|
||||
new_val =
|
||||
channel->min_value + new_val * ((gdouble) channel->max_value -
|
||||
(gdouble) channel->min_value);
|
||||
|
||||
gst_color_balance_set_value (balance_element, channel,
|
||||
(gint) (new_val + 0.5));
|
||||
|
||||
gst_object_unref (balance_element);
|
||||
}
|
||||
|
||||
gst_color_balance_value_changed (balance, proxy, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_play_sink_colorbalance_get_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * proxy)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (balance);
|
||||
GList *l;
|
||||
gint i;
|
||||
|
||||
for (i = 0, l = playsink->colorbalance_channels; l; l = l->next, i++) {
|
||||
GstColorBalanceChannel *proxy_tmp = l->data;
|
||||
|
||||
if (proxy_tmp != proxy)
|
||||
continue;
|
||||
|
||||
return playsink->colorbalance_values[i];
|
||||
}
|
||||
|
||||
g_return_val_if_reached (0);
|
||||
}
|
||||
|
||||
static GstColorBalanceType
|
||||
gst_play_sink_colorbalance_get_balance_type (GstColorBalance * balance)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK (balance);
|
||||
GstColorBalance *balance_element = NULL;
|
||||
GstColorBalanceType t = GST_COLOR_BALANCE_SOFTWARE;
|
||||
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
if (playsink->colorbalance_element)
|
||||
balance_element =
|
||||
GST_COLOR_BALANCE (gst_object_ref (playsink->colorbalance_element));
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
|
||||
if (balance_element) {
|
||||
t = gst_color_balance_get_balance_type (balance_element);
|
||||
gst_object_unref (balance_element);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_colorbalance_init (gpointer g_iface, gpointer g_iface_data)
|
||||
{
|
||||
GstColorBalanceInterface *iface = (GstColorBalanceInterface *) g_iface;
|
||||
|
||||
iface->list_channels = gst_play_sink_colorbalance_list_channels;
|
||||
iface->set_value = gst_play_sink_colorbalance_set_value;
|
||||
iface->get_value = gst_play_sink_colorbalance_get_value;
|
||||
iface->get_balance_type = gst_play_sink_colorbalance_get_balance_type;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_play_sink_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
GST_DEBUG_CATEGORY_INIT (gst_play_sink_debug, "playsink", 0, "play bin");
|
||||
|
||||
return gst_element_register (plugin, "playsink", GST_RANK_NONE,
|
||||
GST_TYPE_PLAY_SINK);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,6 @@ gst_play_sink_audio_convert_add_conversion_elements (GstPlaySinkAudioConvert *
|
|||
el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
|
||||
"audioresample", "resample");
|
||||
if (el) {
|
||||
|
||||
if (prev) {
|
||||
if (!gst_element_link_pads_full (prev, "src", el, "sink",
|
||||
GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
|
||||
|
|
|
@ -34,6 +34,13 @@ GST_DEBUG_CATEGORY_STATIC (gst_play_sink_video_convert_debug);
|
|||
G_DEFINE_TYPE (GstPlaySinkVideoConvert, gst_play_sink_video_convert,
|
||||
GST_TYPE_PLAY_SINK_CONVERT_BIN);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_USE_CONVERTERS,
|
||||
PROP_USE_BALANCE,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gst_play_sink_video_convert_add_conversion_elements (GstPlaySinkVideoConvert *
|
||||
self)
|
||||
|
@ -41,22 +48,51 @@ gst_play_sink_video_convert_add_conversion_elements (GstPlaySinkVideoConvert *
|
|||
GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
|
||||
GstElement *el, *prev = NULL;
|
||||
|
||||
el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
|
||||
COLORSPACE, "conv");
|
||||
if (el)
|
||||
prev = el;
|
||||
g_assert (cbin->conversion_elements == NULL);
|
||||
|
||||
el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
|
||||
"videoscale", "scale");
|
||||
if (el) {
|
||||
/* Add black borders if necessary to keep the DAR */
|
||||
g_object_set (el, "add-borders", TRUE, NULL);
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"Building video conversion with use-converters %d, use-balance %d",
|
||||
self->use_converters, self->use_balance);
|
||||
|
||||
if (self->use_converters) {
|
||||
el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
|
||||
COLORSPACE, "conv");
|
||||
if (el)
|
||||
prev = el;
|
||||
|
||||
el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
|
||||
"videoscale", "scale");
|
||||
if (el) {
|
||||
/* Add black borders if necessary to keep the DAR */
|
||||
g_object_set (el, "add-borders", TRUE, NULL);
|
||||
if (prev) {
|
||||
if (!gst_element_link_pads_full (prev, "src", el, "sink",
|
||||
GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
|
||||
goto link_failed;
|
||||
}
|
||||
prev = el;
|
||||
}
|
||||
}
|
||||
|
||||
if (self->use_balance && self->balance) {
|
||||
el = self->balance;
|
||||
gst_play_sink_convert_bin_add_conversion_element (cbin, el);
|
||||
if (prev) {
|
||||
if (!gst_element_link_pads_full (prev, "src", el, "sink",
|
||||
GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
|
||||
goto link_failed;
|
||||
}
|
||||
prev = el;
|
||||
|
||||
el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
|
||||
COLORSPACE, "conv2");
|
||||
if (prev) {
|
||||
if (!gst_element_link_pads_full (prev, "src", el, "sink",
|
||||
GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
|
||||
goto link_failed;
|
||||
}
|
||||
if (el)
|
||||
prev = el;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -65,16 +101,101 @@ link_failed:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_video_convert_finalize (GObject * object)
|
||||
{
|
||||
GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
|
||||
|
||||
if (self->balance)
|
||||
gst_object_unref (self->balance);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_video_convert_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
|
||||
gboolean v, changed = FALSE;
|
||||
|
||||
GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
|
||||
switch (prop_id) {
|
||||
case PROP_USE_CONVERTERS:
|
||||
v = g_value_get_boolean (value);
|
||||
if (v != self->use_converters) {
|
||||
self->use_converters = v;
|
||||
changed = TRUE;
|
||||
}
|
||||
break;
|
||||
case PROP_USE_BALANCE:
|
||||
v = g_value_get_boolean (value);
|
||||
if (v != self->use_balance) {
|
||||
self->use_balance = v;
|
||||
changed = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
|
||||
GST_DEBUG_OBJECT (self, "Rebuilding converter bin");
|
||||
gst_play_sink_convert_bin_remove_elements (cbin);
|
||||
gst_play_sink_video_convert_add_conversion_elements (self);
|
||||
gst_play_sink_convert_bin_add_identity (cbin);
|
||||
gst_play_sink_convert_bin_cache_converter_caps (cbin);
|
||||
}
|
||||
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_video_convert_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
|
||||
|
||||
GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
|
||||
switch (prop_id) {
|
||||
case PROP_USE_CONVERTERS:
|
||||
g_value_set_boolean (value, self->use_converters);
|
||||
break;
|
||||
case PROP_USE_BALANCE:
|
||||
g_value_set_boolean (value, self->use_balance);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_video_convert_class_init (GstPlaySinkVideoConvertClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_play_sink_video_convert_debug,
|
||||
"playsinkvideoconvert", 0, "play bin");
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_play_sink_video_convert_finalize;
|
||||
gobject_class->set_property = gst_play_sink_video_convert_set_property;
|
||||
gobject_class->get_property = gst_play_sink_video_convert_get_property;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_USE_CONVERTERS,
|
||||
g_param_spec_boolean ("use-converters", "Use converters",
|
||||
"Whether to use conversion elements", FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_USE_BALANCE,
|
||||
g_param_spec_boolean ("use-balance", "Use balance",
|
||||
"Whether to use a videobalance element", FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_set_details_simple (gstelement_class,
|
||||
"Player Sink Video Converter", "Video/Bin/Converter",
|
||||
"Convenience bin for video conversion",
|
||||
|
@ -87,6 +208,14 @@ gst_play_sink_video_convert_init (GstPlaySinkVideoConvert * self)
|
|||
GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
|
||||
cbin->audio = FALSE;
|
||||
|
||||
/* FIXME: Only create this on demand but for now we need
|
||||
* it to always exist because of playsink's color balance
|
||||
* proxying logic.
|
||||
*/
|
||||
self->balance = gst_element_factory_make ("videobalance", "videobalance");
|
||||
if (self->balance)
|
||||
gst_object_ref_sink (self->balance);
|
||||
|
||||
gst_play_sink_video_convert_add_conversion_elements (self);
|
||||
gst_play_sink_convert_bin_cache_converter_caps (cbin);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ struct _GstPlaySinkVideoConvert
|
|||
{
|
||||
GstPlaySinkConvertBin parent;
|
||||
|
||||
/* < pseudo public > */
|
||||
GstElement *balance;
|
||||
gboolean use_converters;
|
||||
gboolean use_balance;
|
||||
};
|
||||
|
||||
struct _GstPlaySinkVideoConvertClass
|
||||
|
|
|
@ -395,10 +395,121 @@ gst_video_scale_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
}
|
||||
|
||||
#define NEAREST (1 << GST_VIDEO_SCALE_NEAREST)
|
||||
#define BILINEAR (1 << GST_VIDEO_SCALE_BILINEAR)
|
||||
#define FOURTAP (1 << GST_VIDEO_SCALE_4TAP)
|
||||
#define LANCZOS (1 << GST_VIDEO_SCALE_LANCZOS)
|
||||
|
||||
/* or we could just do lookups via table[format] if we could be bothered.. */
|
||||
static const struct
|
||||
{
|
||||
GstVideoFormat format;
|
||||
guint8 methods;
|
||||
} formats_methods_table[] = {
|
||||
{
|
||||
GST_VIDEO_FORMAT_RGBx, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_xRGB, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_BGRx, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_xBGR, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_RGBA, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_ARGB, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_BGRA, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_ABGR, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_AYUV, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_ARGB64, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_AYUV64, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_RGB, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_BGR, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_v308, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_YUY2, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_YVYU, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_UYVY, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_Y800, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_GRAY8, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_GRAY16_LE, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_GRAY16_BE, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_Y16, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_I420, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_YV12, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_Y444, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_Y42B, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_Y41B, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
|
||||
GST_VIDEO_FORMAT_NV12, NEAREST | BILINEAR}, {
|
||||
GST_VIDEO_FORMAT_RGB16, NEAREST | BILINEAR | FOURTAP}, {
|
||||
GST_VIDEO_FORMAT_RGB15, NEAREST | BILINEAR | FOURTAP}
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gst_video_scale_format_supported_for_method (GstVideoFormat format,
|
||||
GstVideoScaleMethod method)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (formats_methods_table); ++i) {
|
||||
if (formats_methods_table[i].format == format)
|
||||
return ((formats_methods_table[i].methods & (1 << method)) != 0);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_video_scale_transform_supported (GstVideoScale * videoscale,
|
||||
GstVideoScaleMethod method, GstStructure * structure)
|
||||
{
|
||||
const GValue *val;
|
||||
GstVideoInfo info;
|
||||
gboolean supported = TRUE;
|
||||
GstStructure *s;
|
||||
GstCaps *c;
|
||||
|
||||
/* we support these methods for all formats */
|
||||
if (method == GST_VIDEO_SCALE_NEAREST || method == GST_VIDEO_SCALE_BILINEAR)
|
||||
return TRUE;
|
||||
|
||||
/* we need fixed caps if we want to use gst_video_parse_caps() */
|
||||
s = gst_structure_new (gst_structure_get_name (structure),
|
||||
"width", G_TYPE_INT, 1, "height", G_TYPE_INT, 1, NULL);
|
||||
|
||||
if ((val = gst_structure_get_value (structure, "format"))) {
|
||||
gst_structure_set_value (s, "format", val);
|
||||
} else {
|
||||
if ((val = gst_structure_get_value (structure, "endianness")))
|
||||
gst_structure_set_value (s, "endianness", val);
|
||||
if ((val = gst_structure_get_value (structure, "red_mask")))
|
||||
gst_structure_set_value (s, "red_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "blue_mask")))
|
||||
gst_structure_set_value (s, "blue_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "green_mask")))
|
||||
gst_structure_set_value (s, "green_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "alpha_mask")))
|
||||
gst_structure_set_value (s, "alpha_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "depth")))
|
||||
gst_structure_set_value (s, "depth", val);
|
||||
if ((val = gst_structure_get_value (structure, "bpp")))
|
||||
gst_structure_set_value (s, "bpp", val);
|
||||
}
|
||||
c = gst_caps_new_full (s, NULL);
|
||||
|
||||
gst_video_info_init (&info);
|
||||
if (!gst_video_info_from_caps (&info, c)) {
|
||||
GST_ERROR_OBJECT (videoscale, "couldn't parse %" GST_PTR_FORMAT, c);
|
||||
} else if (!gst_video_scale_format_supported_for_method (info.finfo->format,
|
||||
method)) {
|
||||
supported = FALSE;
|
||||
}
|
||||
GST_LOG_OBJECT (videoscale, "method %d %ssupported for format %d",
|
||||
method, (supported) ? "" : "not ", info.finfo->format);
|
||||
gst_caps_unref (c);
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_video_scale_transform_caps (GstBaseTransform * trans,
|
||||
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
|
||||
{
|
||||
GstVideoScale *videoscale = GST_VIDEO_SCALE (trans);
|
||||
GstVideoScaleMethod method;
|
||||
GstCaps *ret;
|
||||
GstStructure *structure;
|
||||
gint i, n;
|
||||
|
@ -407,6 +518,10 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
|
|||
"Transforming caps %" GST_PTR_FORMAT " in direction %s", caps,
|
||||
(direction == GST_PAD_SINK) ? "sink" : "src");
|
||||
|
||||
GST_OBJECT_LOCK (videoscale);
|
||||
method = videoscale->method;
|
||||
GST_OBJECT_UNLOCK (videoscale);
|
||||
|
||||
ret = gst_caps_new_empty ();
|
||||
n = gst_caps_get_size (caps);
|
||||
for (i = 0; i < n; i++) {
|
||||
|
@ -417,6 +532,9 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
|
|||
if (i > 0 && gst_caps_is_subset_structure (ret, structure))
|
||||
continue;
|
||||
|
||||
if (!gst_video_scale_transform_supported (videoscale, method, structure))
|
||||
goto format_not_supported;
|
||||
|
||||
structure = gst_structure_copy (structure);
|
||||
gst_structure_set (structure,
|
||||
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
|
@ -439,9 +557,19 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
|
|||
ret = intersection;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
|
||||
|
||||
return ret;
|
||||
|
||||
format_not_supported:
|
||||
{
|
||||
gst_structure_free (structure);
|
||||
gst_caps_unref (ret);
|
||||
ret = gst_caps_new_empty ();
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -109,6 +109,10 @@
|
|||
|
||||
/* for developers: there are two useful tools : xvinfo and xvattr */
|
||||
|
||||
/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
|
||||
* with newer GLib versions (>= 2.31.0) */
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
|
|
@ -101,8 +101,8 @@ GST_START_TEST (test_event)
|
|||
GstBus *bus;
|
||||
GstEvent *seek_event;
|
||||
gboolean res;
|
||||
GstPad *srcpad;
|
||||
GstStreamConsistency *consist;
|
||||
GstPad *srcpad, *sinkpad;
|
||||
GstStreamConsistency *chk_1, *chk_2, *chk_3;
|
||||
|
||||
GST_INFO ("preparing test");
|
||||
|
||||
|
@ -130,7 +130,22 @@ GST_START_TEST (test_event)
|
|||
fail_unless (res == TRUE, NULL);
|
||||
|
||||
srcpad = gst_element_get_static_pad (adder, "src");
|
||||
consist = gst_consistency_checker_new (srcpad);
|
||||
chk_3 = gst_consistency_checker_new (srcpad);
|
||||
gst_object_unref (srcpad);
|
||||
|
||||
/* create consistency checkers for the pads */
|
||||
srcpad = gst_element_get_static_pad (src1, "src");
|
||||
chk_1 = gst_consistency_checker_new (srcpad);
|
||||
sinkpad = gst_pad_get_peer (srcpad);
|
||||
gst_consistency_checker_add_pad (chk_3, sinkpad);
|
||||
gst_object_unref (sinkpad);
|
||||
gst_object_unref (srcpad);
|
||||
|
||||
srcpad = gst_element_get_static_pad (src2, "src");
|
||||
chk_2 = gst_consistency_checker_new (srcpad);
|
||||
sinkpad = gst_pad_get_peer (srcpad);
|
||||
gst_consistency_checker_add_pad (chk_3, sinkpad);
|
||||
gst_object_unref (sinkpad);
|
||||
gst_object_unref (srcpad);
|
||||
|
||||
seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
|
||||
|
@ -174,7 +189,9 @@ GST_START_TEST (test_event)
|
|||
|
||||
/* cleanup */
|
||||
g_main_loop_unref (main_loop);
|
||||
gst_consistency_checker_free (consist);
|
||||
gst_consistency_checker_free (chk_1);
|
||||
gst_consistency_checker_free (chk_2);
|
||||
gst_consistency_checker_free (chk_3);
|
||||
gst_object_unref (G_OBJECT (bus));
|
||||
gst_object_unref (G_OBJECT (bin));
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
|
||||
* with newer GLib versions (>= 2.31.0) */
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <gst/check/gstcheck.h>
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
|
||||
* with newer GLib versions (>= 2.31.0) */
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
|
|
@ -30,22 +30,20 @@
|
|||
#define LINK_CHECK_FLAGS GST_PAD_LINK_CHECK_NOTHING
|
||||
|
||||
static GstCaps **
|
||||
videoscale_get_allowed_caps (void)
|
||||
videoscale_get_allowed_caps_for_method (int method)
|
||||
{
|
||||
GstElement *scale = gst_element_factory_make ("videoscale", "scale");
|
||||
GstPadTemplate *templ;
|
||||
GstCaps *tmp, *caps, **ret;
|
||||
GstElement *scale;
|
||||
GstCaps *caps, **ret;
|
||||
GstPad *pad;
|
||||
GstStructure *s;
|
||||
gint i, n;
|
||||
|
||||
templ =
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (scale),
|
||||
"sink");
|
||||
fail_unless (templ != NULL);
|
||||
|
||||
tmp = gst_pad_template_get_caps (templ);
|
||||
caps = gst_caps_normalize (tmp);
|
||||
gst_caps_unref (tmp);
|
||||
scale = gst_element_factory_make ("videoscale", "vscale");
|
||||
g_object_set (scale, "method", method, NULL);
|
||||
pad = gst_element_get_static_pad (scale, "sink");
|
||||
caps = gst_pad_query_caps (pad, NULL);
|
||||
gst_object_unref (pad);
|
||||
gst_object_unref (scale);
|
||||
|
||||
n = gst_caps_get_size (caps);
|
||||
ret = g_new0 (GstCaps *, n + 1);
|
||||
|
@ -54,10 +52,10 @@ videoscale_get_allowed_caps (void)
|
|||
s = gst_caps_get_structure (caps, i);
|
||||
ret[i] = gst_caps_new_empty ();
|
||||
gst_caps_append_structure (ret[i], gst_structure_copy (s));
|
||||
GST_LOG ("method %d supports: %" GST_PTR_FORMAT, method, s);
|
||||
}
|
||||
|
||||
gst_caps_unref (caps);
|
||||
gst_object_unref (scale);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -212,15 +210,15 @@ on_src_handoff_passthrough (GstElement * element, GstBuffer * buffer,
|
|||
*list = g_list_prepend (*list, gst_buffer_ref (buffer));
|
||||
}
|
||||
|
||||
GST_START_TEST (test_passthrough)
|
||||
static void
|
||||
test_passthrough (int method)
|
||||
{
|
||||
GList *l1, *l2, *src_buffers = NULL, *sink_buffers = NULL;
|
||||
GstCaps **allowed_caps = NULL, **p;
|
||||
gint method;
|
||||
static const gint src_width = 640, src_height = 480;
|
||||
static const gint dest_width = 640, dest_height = 480;
|
||||
|
||||
p = allowed_caps = videoscale_get_allowed_caps ();
|
||||
p = allowed_caps = videoscale_get_allowed_caps_for_method (method);
|
||||
|
||||
while (*p) {
|
||||
GstCaps *caps = *p;
|
||||
|
@ -263,13 +261,38 @@ GST_START_TEST (test_passthrough)
|
|||
g_list_free (sink_buffers);
|
||||
sink_buffers = NULL;
|
||||
}
|
||||
|
||||
gst_caps_unref (caps);
|
||||
p++;
|
||||
}
|
||||
g_free (allowed_caps);
|
||||
}
|
||||
|
||||
GST_START_TEST (test_passthrough_method_0)
|
||||
{
|
||||
test_passthrough (0);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_passthrough_method_1)
|
||||
{
|
||||
test_passthrough (1);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_passthrough_method_2)
|
||||
{
|
||||
test_passthrough (2);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_passthrough_method_3)
|
||||
{
|
||||
test_passthrough (3);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
#define CREATE_TEST(name,method,src_width,src_height,dest_width,dest_height) \
|
||||
|
@ -277,7 +300,7 @@ GST_START_TEST (name) \
|
|||
{ \
|
||||
GstCaps **allowed_caps = NULL, **p; \
|
||||
\
|
||||
p = allowed_caps = videoscale_get_allowed_caps (); \
|
||||
p = allowed_caps = videoscale_get_allowed_caps_for_method (method); \
|
||||
\
|
||||
while (*p) { \
|
||||
GstCaps *caps = *p; \
|
||||
|
@ -299,39 +322,51 @@ GST_END_TEST;
|
|||
CREATE_TEST (test_downscale_640x480_320x240_method_0, 0, 640, 480, 320, 240);
|
||||
CREATE_TEST (test_downscale_640x480_320x240_method_1, 1, 640, 480, 320, 240);
|
||||
CREATE_TEST (test_downscale_640x480_320x240_method_2, 2, 640, 480, 320, 240);
|
||||
CREATE_TEST (test_downscale_640x480_320x240_method_3, 3, 640, 480, 320, 240);
|
||||
CREATE_TEST (test_upscale_320x240_640x480_method_0, 0, 320, 240, 640, 480);
|
||||
CREATE_TEST (test_upscale_320x240_640x480_method_1, 1, 320, 240, 640, 480);
|
||||
CREATE_TEST (test_upscale_320x240_640x480_method_2, 2, 320, 240, 640, 480);
|
||||
CREATE_TEST (test_upscale_320x240_640x480_method_3, 3, 320, 240, 640, 480);
|
||||
CREATE_TEST (test_downscale_640x480_1x1_method_0, 0, 640, 480, 1, 1);
|
||||
CREATE_TEST (test_downscale_640x480_1x1_method_1, 1, 640, 480, 1, 1);
|
||||
CREATE_TEST (test_downscale_640x480_1x1_method_2, 2, 640, 480, 1, 1);
|
||||
CREATE_TEST (test_downscale_640x480_1x1_method_3, 3, 640, 480, 1, 1);
|
||||
CREATE_TEST (test_upscale_1x1_640x480_method_0, 0, 1, 1, 640, 480);
|
||||
CREATE_TEST (test_upscale_1x1_640x480_method_1, 1, 1, 1, 640, 480);
|
||||
CREATE_TEST (test_upscale_1x1_640x480_method_2, 2, 1, 1, 640, 480);
|
||||
CREATE_TEST (test_upscale_1x1_640x480_method_3, 3, 1, 1, 640, 480);
|
||||
CREATE_TEST (test_downscale_641x481_111x30_method_0, 0, 641, 481, 111, 30);
|
||||
CREATE_TEST (test_downscale_641x481_111x30_method_1, 1, 641, 481, 111, 30);
|
||||
CREATE_TEST (test_downscale_641x481_111x30_method_2, 2, 641, 481, 111, 30);
|
||||
CREATE_TEST (test_downscale_641x481_111x30_method_3, 3, 641, 481, 111, 30);
|
||||
CREATE_TEST (test_upscale_111x30_641x481_method_0, 0, 111, 30, 641, 481);
|
||||
CREATE_TEST (test_upscale_111x30_641x481_method_1, 1, 111, 30, 641, 481);
|
||||
CREATE_TEST (test_upscale_111x30_641x481_method_2, 2, 111, 30, 641, 481);
|
||||
CREATE_TEST (test_upscale_111x30_641x481_method_3, 2, 111, 30, 641, 481);
|
||||
CREATE_TEST (test_downscale_641x481_30x111_method_0, 0, 641, 481, 30, 111);
|
||||
CREATE_TEST (test_downscale_641x481_30x111_method_1, 1, 641, 481, 30, 111);
|
||||
CREATE_TEST (test_downscale_641x481_30x111_method_2, 2, 641, 481, 30, 111);
|
||||
CREATE_TEST (test_downscale_641x481_30x111_method_3, 3, 641, 481, 30, 111);
|
||||
CREATE_TEST (test_upscale_30x111_641x481_method_0, 0, 30, 111, 641, 481);
|
||||
CREATE_TEST (test_upscale_30x111_641x481_method_1, 1, 30, 111, 641, 481);
|
||||
CREATE_TEST (test_upscale_30x111_641x481_method_2, 2, 30, 111, 641, 481);
|
||||
CREATE_TEST (test_upscale_30x111_641x481_method_3, 3, 30, 111, 641, 481);
|
||||
CREATE_TEST (test_downscale_640x480_320x1_method_0, 0, 640, 480, 320, 1);
|
||||
CREATE_TEST (test_downscale_640x480_320x1_method_1, 1, 640, 480, 320, 1);
|
||||
CREATE_TEST (test_downscale_640x480_320x1_method_2, 2, 640, 480, 320, 1);
|
||||
CREATE_TEST (test_downscale_640x480_320x1_method_3, 3, 640, 480, 320, 1);
|
||||
CREATE_TEST (test_upscale_320x1_640x480_method_0, 0, 320, 1, 640, 480);
|
||||
CREATE_TEST (test_upscale_320x1_640x480_method_1, 1, 320, 1, 640, 480);
|
||||
CREATE_TEST (test_upscale_320x1_640x480_method_2, 2, 320, 1, 640, 480);
|
||||
CREATE_TEST (test_upscale_320x1_640x480_method_3, 3, 320, 1, 640, 480);
|
||||
CREATE_TEST (test_downscale_640x480_1x240_method_0, 0, 640, 480, 1, 240);
|
||||
CREATE_TEST (test_downscale_640x480_1x240_method_1, 1, 640, 480, 1, 240);
|
||||
CREATE_TEST (test_downscale_640x480_1x240_method_2, 2, 640, 480, 1, 240);
|
||||
CREATE_TEST (test_downscale_640x480_1x240_method_3, 3, 640, 480, 1, 240);
|
||||
CREATE_TEST (test_upscale_1x240_640x480_method_0, 0, 1, 240, 640, 480);
|
||||
CREATE_TEST (test_upscale_1x240_640x480_method_1, 1, 1, 240, 640, 480);
|
||||
CREATE_TEST (test_upscale_1x240_640x480_method_2, 2, 1, 240, 640, 480);
|
||||
CREATE_TEST (test_upscale_1x240_640x480_method_3, 3, 1, 240, 640, 480);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -823,6 +858,13 @@ GST_START_TEST (test_basetransform_negotiation)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
#ifndef tcase_skip_broken_test
|
||||
#define tcase_skip_broken_test(chain,test_func) \
|
||||
if (0) { tcase_add_test(chain,test_func); } else { \
|
||||
GST_ERROR ("FIXME: skipping test %s because it's broken.", G_STRINGIFY (test_func)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
static Suite *
|
||||
videoscale_suite (void)
|
||||
{
|
||||
|
@ -831,43 +873,58 @@ videoscale_suite (void)
|
|||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_set_timeout (tc_chain, 180);
|
||||
tcase_add_test (tc_chain, test_passthrough);
|
||||
tcase_add_test (tc_chain, test_passthrough_method_0);
|
||||
tcase_add_test (tc_chain, test_passthrough_method_1);
|
||||
tcase_add_test (tc_chain, test_passthrough_method_2);
|
||||
tcase_add_test (tc_chain, test_passthrough_method_3);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_0);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_1);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_2);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_3);
|
||||
tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_0);
|
||||
tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_1);
|
||||
tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_2);
|
||||
tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_3);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_0);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_1);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_2);
|
||||
tcase_skip_broken_test (tc_chain, test_downscale_640x480_1x1_method_3);
|
||||
tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_0);
|
||||
tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_1);
|
||||
tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_2);
|
||||
tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_3);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_0);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_1);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_2);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_3);
|
||||
tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_0);
|
||||
tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_1);
|
||||
tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_2);
|
||||
tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_3);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_0);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_1);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_2);
|
||||
tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_3);
|
||||
tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_0);
|
||||
tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_1);
|
||||
tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_2);
|
||||
tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_3);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_0);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_1);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_2);
|
||||
tcase_skip_broken_test (tc_chain, test_downscale_640x480_320x1_method_3);
|
||||
tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_0);
|
||||
tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_1);
|
||||
tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_2);
|
||||
tcase_skip_broken_test (tc_chain, test_upscale_320x1_640x480_method_3);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_0);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_1);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_2);
|
||||
tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_3);
|
||||
tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_0);
|
||||
tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_1);
|
||||
tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_2);
|
||||
tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_3);
|
||||
tcase_add_test (tc_chain, test_negotiation);
|
||||
#if 0
|
||||
tcase_add_test (tc_chain, test_reverse_negotiation);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,8 +22,10 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
|
||||
* with newer GTK versions (>= 3.3.0) */
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
#define GDK_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -53,9 +53,6 @@
|
|||
/* system wide data directory */
|
||||
#define GST_DATADIR PREFIX "\\share"
|
||||
|
||||
/* set to disable libxml2-dependent code in subparse */
|
||||
#undef GST_DISABLE_XML
|
||||
|
||||
/* Extra platform specific plugin suffix */
|
||||
#undef GST_EXTRA_MODULE_SUFFIX
|
||||
|
||||
|
@ -152,6 +149,9 @@
|
|||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <emmintrin.h> header file. */
|
||||
#undef HAVE_EMMINTRIN_H
|
||||
|
||||
/* Define to enable building of experimental plug-ins. */
|
||||
#undef HAVE_EXPERIMENTAL
|
||||
|
||||
|
@ -272,6 +272,9 @@
|
|||
/* Define to enable X libraries and plugins (used by ximagesink). */
|
||||
#undef HAVE_X
|
||||
|
||||
/* Define to 1 if you have the <xmmintrin.h> header file. */
|
||||
#undef HAVE_XMMINTRIN_H
|
||||
|
||||
/* Define to enable X Shared Memory extension. */
|
||||
#undef HAVE_XSHM
|
||||
|
||||
|
|
Loading…
Reference in a new issue