[totem] backend: Implement variable playback rate with pitch adjustment
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem] backend: Implement variable playback rate with pitch adjustment
- Date: Thu, 29 Mar 2012 00:59:33 +0000 (UTC)
commit 135a476948343f0bce7ce3f6af2919a6696e28ed
Author: Vasilis Liaskovitis <vliaskov gmail com>
Date: Wed Mar 14 22:18:30 2012 +0100
backend: Implement variable playback rate with pitch adjustment
https://bugzilla.gnome.org/show_bug.cgi?id=417141
configure.in | 15 +++++
src/backend/bacon-video-widget-gst-0.10.c | 87 ++++++++++++++++++++++++++++-
src/backend/bacon-video-widget.h | 8 +++
3 files changed, 107 insertions(+), 3 deletions(-)
---
diff --git a/configure.in b/configure.in
index 64dea74..7957d7b 100644
--- a/configure.in
+++ b/configure.in
@@ -166,6 +166,21 @@ do
fi
done
+dnl Check for elements from gst-plugins-bad
+for bad_element in pitch
+do
+ AC_MSG_CHECKING([GStreamer 0.10 $bad_element plugin])
+ if $gst010_inspect $bad_element >/dev/null 2>/dev/null; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([
+ Cannot find required GStreamer-0.10 plugin '$bad_element'.
+ It should be part of gst-plugins-bad. Please install it.
+ ])
+ fi
+done
+
dnl Check the smclient backend
AC_MSG_CHECKING([which smclient backend to use])
AC_ARG_WITH([smclient],
diff --git a/src/backend/bacon-video-widget-gst-0.10.c b/src/backend/bacon-video-widget-gst-0.10.c
index 101d227..0a9ab3e 100644
--- a/src/backend/bacon-video-widget-gst-0.10.c
+++ b/src/backend/bacon-video-widget-gst-0.10.c
@@ -207,6 +207,7 @@ struct BaconVideoWidgetPrivate
BvwVisualizationQuality visq;
gchar *vis_element_name;
GstElement *audio_capsfilter;
+ GstElement *audio_pitchcontrol;
/* Other stuff */
gboolean logo_mode;
@@ -3664,9 +3665,8 @@ bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw,
return FALSE;
bvw->priv->seek_time = -1;
- bvw->priv->rate = FORWARD_RATE;
- gst_element_seek (bvw->priv->play, FORWARD_RATE,
+ gst_element_seek (bvw->priv->play, bvw->priv->rate,
GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | flag,
GST_SEEK_TYPE_SET, _time * GST_MSECOND,
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
@@ -3911,6 +3911,7 @@ bacon_video_widget_close (BaconVideoWidget * bvw)
bvw->priv->has_angles = FALSE;
bvw->priv->window_resized = FALSE;
bvw->priv->rate = FORWARD_RATE;
+ g_object_set (bvw->priv->audio_pitchcontrol, "pitch", 1.0, NULL);
bvw->priv->seek_req_time = GST_CLOCK_TIME_NONE;
bvw->priv->seek_time = -1;
@@ -4024,6 +4025,7 @@ bacon_video_widget_dvd_event (BaconVideoWidget * bvw,
gst_element_seek (bvw->priv->play, FORWARD_RATE, fmt, GST_SEEK_FLAG_FLUSH,
GST_SEEK_TYPE_SET, val, GST_SEEK_TYPE_NONE, 0);
bvw->priv->rate = FORWARD_RATE;
+ g_object_set (bvw->priv->audio_pitchcontrol, "pitch", 1.0, NULL);
} else {
GST_DEBUG ("failed to query position (%s)", fmt_name);
}
@@ -6010,6 +6012,7 @@ bvw_set_playback_direction (BaconVideoWidget *bvw, gboolean forward)
} else {
gst_element_get_state (bvw->priv->play, NULL, NULL, GST_CLOCK_TIME_NONE);
bvw->priv->rate = REVERSE_RATE;
+ g_object_set (bvw->priv->audio_pitchcontrol, "pitch", 1.0, NULL);
retval = TRUE;
}
} else {
@@ -6033,6 +6036,7 @@ bvw_set_playback_direction (BaconVideoWidget *bvw, gboolean forward)
} else {
gst_element_get_state (bvw->priv->play, NULL, NULL, GST_CLOCK_TIME_NONE);
bvw->priv->rate = FORWARD_RATE;
+ g_object_set (bvw->priv->audio_pitchcontrol, "pitch", 1.0, NULL);
retval = TRUE;
}
} else {
@@ -6246,9 +6250,14 @@ bacon_video_widget_new (GError ** error)
bvw->priv->audio_capsfilter =
gst_element_factory_make ("capsfilter", "audiofilter");
audio_bin = gst_bin_new ("audiosinkbin");
+ bvw->priv->audio_pitchcontrol =
+ gst_element_factory_make ("pitch", "audiopitch");
+ g_object_set (bvw->priv->audio_pitchcontrol, "pitch", 1.0, NULL);
gst_bin_add_many (GST_BIN (audio_bin), bvw->priv->audio_capsfilter,
- audio_sink, NULL);
+ bvw->priv->audio_pitchcontrol, audio_sink, NULL);
gst_element_link_pads (bvw->priv->audio_capsfilter, "src",
+ bvw->priv->audio_pitchcontrol, "sink");
+ gst_element_link_pads (bvw->priv->audio_pitchcontrol, "src",
audio_sink, "sink");
audio_pad = gst_element_get_static_pad (bvw->priv->audio_capsfilter, "sink");
@@ -6306,6 +6315,78 @@ sink_error:
}
}
+gfloat
+bacon_video_widget_get_rate (BaconVideoWidget *bvw)
+{
+ return bvw->priv->rate;
+}
+
+gboolean
+bacon_video_widget_set_rate (BaconVideoWidget *bvw, gfloat new_rate)
+{
+ GstEvent *event;
+ gboolean retval = FALSE;
+ GstFormat fmt;
+ gint64 cur;
+ gfloat pitch, ratio;
+
+ g_return_val_if_fail (bvw != NULL, FALSE);
+ g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), FALSE);
+ g_return_val_if_fail (GST_IS_ELEMENT (bvw->priv->play), FALSE);
+
+ /* set upper and lower limit for rate */
+ if (new_rate <= 0.5)
+ return TRUE;
+ if (new_rate >= 2.0)
+ return TRUE;
+ ratio = new_rate / bvw->priv->rate;
+
+ fmt = GST_FORMAT_TIME;
+
+ if (gst_element_query_position (bvw->priv->play, &fmt, &cur)) {
+ GST_DEBUG ("Setting playback direction to reverse at %"G_GINT64_FORMAT"", cur);
+ event = gst_event_new_seek (new_rate,
+ fmt, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
+ GST_SEEK_TYPE_SET, cur,
+ GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE);
+ if (gst_element_send_event (bvw->priv->play, event) == FALSE) {
+ GST_DEBUG ("Failed to change rate");
+ } else {
+ gst_element_get_state (bvw->priv->play, NULL, NULL, GST_CLOCK_TIME_NONE);
+ bvw->priv->rate = new_rate;
+ g_object_get (bvw->priv->audio_pitchcontrol, "pitch", &pitch, NULL);
+ g_object_set (bvw->priv->audio_pitchcontrol, "pitch", pitch/ratio, NULL);
+ GST_DEBUG ("changed rate to %f, pitch to %f\n", new_rate, pitch);
+ retval = TRUE;
+ }
+ }
+ else {
+ GST_DEBUG ("failed to query position");
+ }
+ return retval;
+}
+
+gboolean
+bacon_video_widget_change_rate (BaconVideoWidget *bvw, gboolean increase)
+{
+ gfloat rate;
+
+ g_return_val_if_fail (bvw != NULL, FALSE);
+ g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), FALSE);
+ g_return_val_if_fail (GST_IS_ELEMENT (bvw->priv->play), FALSE);
+
+ rate = bvw->priv->rate;
+ rate += (increase) ? 0.1 : -0.1;
+
+ return bacon_video_widget_set_rate (bvw, rate);
+}
+
+gboolean
+bacon_video_widget_reset_rate (BaconVideoWidget *bvw)
+{
+ return bacon_video_widget_set_rate (bvw, 1.0);
+}
+
/*
* vim: sw=2 ts=8 cindent noai bs=2
*/
diff --git a/src/backend/bacon-video-widget.h b/src/backend/bacon-video-widget.h
index 30dca40..ace542c 100644
--- a/src/backend/bacon-video-widget.h
+++ b/src/backend/bacon-video-widget.h
@@ -249,6 +249,14 @@ void bacon_video_widget_set_user_agent (BaconVideoWidget *bvw,
void bacon_video_widget_set_referrer (BaconVideoWidget *bvw,
const char *referrer);
+gboolean bacon_video_widget_change_rate (BaconVideoWidget *bvw, gboolean increase);
+
+gboolean bacon_video_widget_set_rate (BaconVideoWidget *bvw, gfloat new_rate);
+
+gboolean bacon_video_widget_reset_rate (BaconVideoWidget *bvw);
+
+gfloat bacon_video_widget_get_rate (BaconVideoWidget *bvw);
+
/* Metadata */
/**
* BvwMetadataType:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]