368 lines
10 KiB
Diff
368 lines
10 KiB
Diff
From e277ba3892378d6562913e2a803f3a126d46c720 Mon Sep 17 00:00:00 2001
|
|
From: Lyon Wang <lyon.wang@nxp.com>
|
|
Date: Fri, 30 Dec 2016 15:53:21 +0800
|
|
Subject: [PATCH 14/26] Specific patches for gstplayer API
|
|
|
|
player: Add get_rotate, set_rotate API
|
|
|
|
- Add gstplayer get_rotate() and set_rotate() API
|
|
|
|
player: Add force-aspect-ratio config
|
|
|
|
- Add get/set force-aspect-ratio config API
|
|
|
|
player: Add set audio / text sink API
|
|
|
|
- Add get/set audio / text sink API
|
|
|
|
Upstream-Status: Inappropriate [i.MX specific]
|
|
|
|
Signed-off-by: Lyon Wang <lyon.wang@nxp.com>
|
|
|
|
Conflicts:
|
|
gst-libs/gst/player/gstplayer.c
|
|
gst-libs/gst/player/gstplayer.h
|
|
---
|
|
gst-libs/gst/player/gstplayer.c | 284 ++++++++++++++++++++++++++++++++++++++++
|
|
gst-libs/gst/player/gstplayer.h | 11 ++
|
|
2 files changed, 295 insertions(+)
|
|
|
|
diff --git a/gst-libs/gst/player/gstplayer.c b/gst-libs/gst/player/gstplayer.c
|
|
index 273a480..92ad919 100644
|
|
--- a/gst-libs/gst/player/gstplayer.c
|
|
+++ b/gst-libs/gst/player/gstplayer.c
|
|
@@ -82,6 +82,7 @@ typedef enum
|
|
CONFIG_QUARK_USER_AGENT = 0,
|
|
CONFIG_QUARK_POSITION_INTERVAL_UPDATE,
|
|
CONFIG_QUARK_ACCURATE_SEEK,
|
|
+ CONFIG_QUARK_FORCE_ASPECT_RATIO,
|
|
|
|
CONFIG_QUARK_MAX
|
|
} ConfigQuarkId;
|
|
@@ -90,6 +91,7 @@ static const gchar *_config_quark_strings[] = {
|
|
"user-agent",
|
|
"position-interval-update",
|
|
"accurate-seek",
|
|
+ "force-aspect-ratio",
|
|
};
|
|
|
|
GQuark _config_quark_table[CONFIG_QUARK_MAX];
|
|
@@ -286,6 +288,7 @@ gst_player_init (GstPlayer * self)
|
|
self->config = gst_structure_new_id (QUARK_CONFIG,
|
|
CONFIG_QUARK (POSITION_INTERVAL_UPDATE), G_TYPE_UINT, DEFAULT_POSITION_UPDATE_INTERVAL_MS,
|
|
CONFIG_QUARK (ACCURATE_SEEK), G_TYPE_BOOLEAN, FALSE,
|
|
+ CONFIG_QUARK (FORCE_ASPECT_RATIO), G_TYPE_BOOLEAN, TRUE,
|
|
NULL);
|
|
/* *INDENT-ON* */
|
|
|
|
@@ -4758,3 +4761,284 @@ gst_player_get_video_snapshot (GstPlayer * self,
|
|
|
|
return sample;
|
|
}
|
|
+
|
|
+/**
|
|
+ * gst_player_get_video_sink:
|
|
+ * @player: #GstPlayer instance
|
|
+ *
|
|
+ * Returns: actual video sink element
|
|
+ */
|
|
+GstElement *
|
|
+gst_player_get_video_sink (GstPlayer * self)
|
|
+{
|
|
+ GstElement *sink = NULL;
|
|
+ GstElement *actual_sink = NULL;
|
|
+ GstIteratorResult rc;
|
|
+ GstIterator *it;
|
|
+ GValue item = { 0, };
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), NULL);
|
|
+
|
|
+ g_object_get (G_OBJECT (self->playbin), "video-sink", &sink, NULL);
|
|
+ if (NULL == sink) {
|
|
+ GST_WARNING_OBJECT (self, "No video-sink found");
|
|
+ return NULL;
|
|
+ }
|
|
+ it = gst_bin_iterate_sinks ((GstBin *) sink);
|
|
+ do {
|
|
+ rc = gst_iterator_next (it, &item);
|
|
+ if (rc == GST_ITERATOR_OK) {
|
|
+ break;
|
|
+ }
|
|
+ } while (rc != GST_ITERATOR_DONE);
|
|
+
|
|
+ g_object_unref (sink);
|
|
+ actual_sink = g_value_get_object (&item);
|
|
+ g_value_unset (&item);
|
|
+ gst_iterator_free (it);
|
|
+
|
|
+ if (NULL == actual_sink) {
|
|
+ GST_WARNING_OBJECT (self, "No video-sink found");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return actual_sink;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_palyer_set_rotate:
|
|
+ * @player: #GstPlayer instance
|
|
+ * @rotation: rotation degree value
|
|
+ *
|
|
+ * Returns: %TRUE or %FALSE
|
|
+ *
|
|
+ * Set the rotation vaule
|
|
+ */
|
|
+gboolean
|
|
+gst_player_set_rotate (GstPlayer * self, gint rotation)
|
|
+{
|
|
+ GstElement *video_sink = NULL;
|
|
+ GObjectClass *gobjclass = NULL;
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), FALSE);
|
|
+
|
|
+ video_sink = gst_player_get_video_sink (self);
|
|
+ if (NULL == video_sink) {
|
|
+ GST_WARNING_OBJECT (self, " cannot get video sink ");
|
|
+ return FALSE;
|
|
+ }
|
|
+ GST_DEBUG_OBJECT (self, "set rotation degree '%d'", rotation);
|
|
+
|
|
+ gobjclass = G_OBJECT_GET_CLASS (G_OBJECT (video_sink));
|
|
+ if (g_object_class_find_property (gobjclass, "rotate")
|
|
+ && g_object_class_find_property (gobjclass, "reconfig")) {
|
|
+ g_object_set (G_OBJECT (video_sink), "rotate", rotation / 90, NULL);
|
|
+ g_object_set (G_OBJECT (video_sink), "reconfig", 1, NULL);
|
|
+ } else if (g_object_class_find_property (gobjclass, "rotate-method")) {
|
|
+ g_object_set (G_OBJECT (video_sink), "rotate-method", rotation / 90, NULL);
|
|
+ } else {
|
|
+ GST_INFO_OBJECT (self, "can't set rotation for current video sink %s'",
|
|
+ gst_element_get_name (video_sink));
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_player_get_rotate:
|
|
+ * @player: #GstPlayer instance
|
|
+ *
|
|
+ * Returns: the rotation degree value
|
|
+ */
|
|
+gint
|
|
+gst_player_get_rotate (GstPlayer * self)
|
|
+{
|
|
+ GstElement *video_sink = NULL;
|
|
+ GObjectClass *gobjclass = NULL;
|
|
+ gint rotation = 0;
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), 0);
|
|
+
|
|
+ video_sink = gst_player_get_video_sink (self);
|
|
+ if (NULL == video_sink) {
|
|
+ GST_WARNING_OBJECT (self, " cannot get video sink ");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* check if the element has "rotate" property */
|
|
+ gobjclass = G_OBJECT_GET_CLASS (video_sink);
|
|
+ if (g_object_class_find_property (gobjclass, "rotate")) {
|
|
+ g_object_get (G_OBJECT (video_sink), "rotate", &rotation, NULL);
|
|
+ rotation = rotation * 90;
|
|
+ } else if (g_object_class_find_property (gobjclass, "rotate-method")) {
|
|
+ g_object_get (G_OBJECT (video_sink), "rotate-method", &rotation, NULL);
|
|
+ rotation = rotation * 90;
|
|
+ }
|
|
+
|
|
+ GST_DEBUG_OBJECT (self, "get rotation degree '%d'", rotation);
|
|
+
|
|
+ return rotation;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_player_config_set_force_aspect_ratio:
|
|
+ * @player: #GstPlayer instance
|
|
+ * @force_aspect_ratio: keey original aspect ratio or not
|
|
+ *
|
|
+ * Enable or disable force aspect ratio
|
|
+ * force_aspect_ratio seeking is TRUE by default.
|
|
+ *
|
|
+ * Since: 1.12
|
|
+ */
|
|
+void
|
|
+gst_player_config_set_force_aspect_ratio (GstPlayer * self, gboolean force_aspect_ratio)
|
|
+{
|
|
+ GstStructure *config = self->config;
|
|
+ g_return_if_fail (config != NULL);
|
|
+
|
|
+ gst_structure_id_set (config,
|
|
+ CONFIG_QUARK (FORCE_ASPECT_RATIO), G_TYPE_BOOLEAN, force_aspect_ratio, NULL);
|
|
+
|
|
+ g_object_set(self->playbin, "force-aspect-ratio", force_aspect_ratio, NULL);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_player_config_get_force_aspect_ratio:
|
|
+ * @config: a #GstPlayer configuration
|
|
+ *
|
|
+ * Returns: %TRUE if force-aspect-ratio is enabled
|
|
+ *
|
|
+ * Since 1.12
|
|
+ */
|
|
+gboolean
|
|
+gst_player_config_get_force_aspect_ratio (const GstStructure * config)
|
|
+{
|
|
+ gboolean force_aspect_ratio = TRUE;
|
|
+
|
|
+ g_return_val_if_fail (config != NULL, FALSE);
|
|
+
|
|
+ gst_structure_id_get (config,
|
|
+ CONFIG_QUARK (FORCE_ASPECT_RATIO), G_TYPE_BOOLEAN, &force_aspect_ratio, NULL);
|
|
+
|
|
+ return force_aspect_ratio;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_player_set_audio_sink:
|
|
+ * @player: #GstPlayer instance
|
|
+ * @audio_sink: the custom audio sink to set
|
|
+ *
|
|
+ * Returns: %TRUE or %FALSE
|
|
+ *
|
|
+ * Set the customize audio sink
|
|
+ */
|
|
+gboolean
|
|
+gst_player_set_audio_sink (GstPlayer * self, GstElement * audio_sink)
|
|
+{
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), FALSE);
|
|
+ g_return_val_if_fail (audio_sink != NULL, FALSE);
|
|
+
|
|
+ g_object_set (G_OBJECT (self->playbin), "audio-sink", audio_sink, NULL);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_player_set_text_sink:
|
|
+ * @player: #GstPlayer instance
|
|
+ * @text_sink: the custom text sink to set
|
|
+ *
|
|
+ * Returns: %TRUE or %FALSE
|
|
+ *
|
|
+ * Set the customize text sink
|
|
+ */
|
|
+gboolean
|
|
+gst_player_set_text_sink (GstPlayer * self, GstElement * text_sink)
|
|
+{
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), FALSE);
|
|
+ g_return_val_if_fail (text_sink != NULL, FALSE);
|
|
+
|
|
+ g_object_set (G_OBJECT (self->playbin), "text-sink", text_sink, NULL);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_player_get_audio_sink:
|
|
+ * @player: #GstPlayer instance
|
|
+ *
|
|
+ * Returns: actual audio sink element
|
|
+ */
|
|
+GstElement *
|
|
+gst_player_get_audio_sink (GstPlayer * self)
|
|
+{
|
|
+ GstElement *sink = NULL;
|
|
+ GstElement *actual_sink = NULL;
|
|
+ GstIteratorResult rc;
|
|
+ GstIterator *it;
|
|
+ GValue item = { 0, };
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), NULL);
|
|
+
|
|
+ g_object_get (G_OBJECT (self->playbin), "audio-sink", &sink, NULL);
|
|
+ if (NULL == sink) {
|
|
+ GST_WARNING_OBJECT (self, "No audio-sink found");
|
|
+ return NULL;
|
|
+ }
|
|
+ it = gst_bin_iterate_sinks ((GstBin *) sink);
|
|
+ do {
|
|
+ rc = gst_iterator_next (it, &item);
|
|
+ if (rc == GST_ITERATOR_OK) {
|
|
+ break;
|
|
+ }
|
|
+ } while (rc != GST_ITERATOR_DONE);
|
|
+
|
|
+ g_object_unref (sink);
|
|
+ actual_sink = g_value_get_object (&item);
|
|
+ g_value_unset (&item);
|
|
+ gst_iterator_free (it);
|
|
+
|
|
+ if (NULL == actual_sink) {
|
|
+ GST_WARNING_OBJECT (self, "No auido-sink found");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return actual_sink;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gst_player_get_text_sink:
|
|
+ * @player: #GstPlayer instance
|
|
+ *
|
|
+ * Returns: actual text sink element
|
|
+ */
|
|
+GstElement *
|
|
+gst_player_get_text_sink (GstPlayer * self)
|
|
+{
|
|
+ GstElement *sink = NULL;
|
|
+ GstElement *actual_sink = NULL;
|
|
+ GstIteratorResult rc;
|
|
+ GstIterator *it;
|
|
+ GValue item = { 0, };
|
|
+ g_return_val_if_fail (GST_IS_PLAYER (self), NULL);
|
|
+
|
|
+ g_object_get (G_OBJECT (self->playbin), "text-sink", &sink, NULL);
|
|
+ if (NULL == sink) {
|
|
+ GST_WARNING_OBJECT (self, "No text-sink found");
|
|
+ return NULL;
|
|
+ }
|
|
+ it = gst_bin_iterate_sinks ((GstBin *) sink);
|
|
+ do {
|
|
+ rc = gst_iterator_next (it, &item);
|
|
+ if (rc == GST_ITERATOR_OK) {
|
|
+ break;
|
|
+ }
|
|
+ } while (rc != GST_ITERATOR_DONE);
|
|
+
|
|
+ g_object_unref (sink);
|
|
+ actual_sink = g_value_get_object (&item);
|
|
+ g_value_unset (&item);
|
|
+ gst_iterator_free (it);
|
|
+
|
|
+ if (NULL == actual_sink) {
|
|
+ GST_WARNING_OBJECT (self, "No text-sink found");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return actual_sink;
|
|
+}
|
|
diff --git a/gst-libs/gst/player/gstplayer.h b/gst-libs/gst/player/gstplayer.h
|
|
index 0338d1a..f444918 100644
|
|
--- a/gst-libs/gst/player/gstplayer.h
|
|
+++ b/gst-libs/gst/player/gstplayer.h
|
|
@@ -216,6 +216,17 @@ typedef enum
|
|
|
|
GstSample * gst_player_get_video_snapshot (GstPlayer * player,
|
|
GstPlayerSnapshotFormat format, GstStructure * config);
|
|
+/* Custom gstplayer API */
|
|
+gboolean gst_player_set_rotate (GstPlayer * player, gint rotation);
|
|
+gint gst_player_get_rotate (GstPlayer * player);
|
|
+
|
|
+void gst_player_config_set_force_aspect_ratio (GstPlayer * self, gboolean force_aspect_ratio);
|
|
+gboolean gst_player_config_get_force_aspect_ratio (const GstStructure * config);
|
|
+
|
|
+gboolean gst_player_set_audio_sink (GstPlayer * player, GstElement * audio_sink);
|
|
+gboolean gst_player_set_text_sink (GstPlayer * player, GstElement * text_sink);
|
|
+GstElement * gst_player_get_audio_sink (GstPlayer * player);
|
|
+GstElement * gst_player_get_text_sink (GstPlayer * player);
|
|
|
|
G_END_DECLS
|
|
|
|
--
|
|
1.9.1
|
|
|