mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-08 00:59:48 +00:00
player: add API to change http user agent
Introducing a new 'config' API similar to GstBufferPoolConfig. https://bugzilla.gnome.org/show_bug.cgi?id=765314
This commit is contained in:
parent
6894682426
commit
6e39cef802
5 changed files with 240 additions and 0 deletions
|
@ -1705,6 +1705,9 @@ gst_player_get_mute
|
|||
|
||||
gst_player_get_pipeline
|
||||
|
||||
gst_player_set_config
|
||||
gst_player_get_config
|
||||
|
||||
gst_player_set_position_update_interval
|
||||
gst_player_get_position_update_interval
|
||||
|
||||
|
@ -1763,6 +1766,10 @@ GstPlayerSignalDispatcherInterface
|
|||
GstPlayerVideoRenderer
|
||||
GstPlayerVideoRendererInterface
|
||||
|
||||
<SUBSECTION config>
|
||||
gst_player_config_set_user_agent
|
||||
gst_player_config_get_user_agent
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GST_IS_PLAYER
|
||||
GST_IS_PLAYER_CLASS
|
||||
|
|
|
@ -78,6 +78,24 @@ gst_player_error_quark (void)
|
|||
return quark;
|
||||
}
|
||||
|
||||
static GQuark QUARK_CONFIG;
|
||||
|
||||
/* Keep ConfigQuarkId and _config_quark_strings ordered and synced */
|
||||
typedef enum
|
||||
{
|
||||
CONFIG_QUARK_USER_AGENT = 0,
|
||||
|
||||
CONFIG_QUARK_MAX
|
||||
} ConfigQuarkId;
|
||||
|
||||
static const gchar *_config_quark_strings[] = {
|
||||
"user-agent",
|
||||
};
|
||||
|
||||
GQuark _config_quark_table[CONFIG_QUARK_MAX];
|
||||
|
||||
#define CONFIG_QUARK(q) _config_quark_table[CONFIG_QUARK_##q]
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -161,6 +179,8 @@ struct _GstPlayer
|
|||
|
||||
GstElement *current_vis_element;
|
||||
|
||||
GstStructure *config;
|
||||
|
||||
/* Protected by lock */
|
||||
gboolean seek_pending; /* Only set from main context */
|
||||
GstClockTime last_seek_time; /* Only set from main context */
|
||||
|
@ -243,6 +263,8 @@ gst_player_init (GstPlayer * self)
|
|||
self->context = g_main_context_new ();
|
||||
self->loop = g_main_loop_new (self->context, FALSE);
|
||||
|
||||
self->config = gst_structure_new_id_empty (QUARK_CONFIG);
|
||||
|
||||
self->position_update_interval_ms = DEFAULT_POSITION_UPDATE_INTERVAL_MS;
|
||||
self->seek_pending = FALSE;
|
||||
self->seek_position = GST_CLOCK_TIME_NONE;
|
||||
|
@ -252,6 +274,23 @@ gst_player_init (GstPlayer * self)
|
|||
GST_TRACE_OBJECT (self, "Initialized");
|
||||
}
|
||||
|
||||
static void
|
||||
config_quark_initialize (void)
|
||||
{
|
||||
gint i;
|
||||
|
||||
QUARK_CONFIG = g_quark_from_static_string ("player-config");
|
||||
|
||||
if (G_N_ELEMENTS (_config_quark_strings) != CONFIG_QUARK_MAX)
|
||||
g_warning ("the quark table is not consistent! %d != %d",
|
||||
(int) G_N_ELEMENTS (_config_quark_strings), CONFIG_QUARK_MAX);
|
||||
|
||||
for (i = 0; i < CONFIG_QUARK_MAX; i++) {
|
||||
_config_quark_table[i] =
|
||||
g_quark_from_static_string (_config_quark_strings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_player_class_init (GstPlayerClass * klass)
|
||||
{
|
||||
|
@ -421,6 +460,8 @@ gst_player_class_init (GstPlayerClass * klass)
|
|||
g_signal_new ("seek-done", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
|
||||
NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_CLOCK_TIME);
|
||||
|
||||
config_quark_initialize ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -463,6 +504,8 @@ gst_player_finalize (GObject * object)
|
|||
g_object_unref (self->signal_dispatcher);
|
||||
if (self->current_vis_element)
|
||||
gst_object_unref (self->current_vis_element);
|
||||
if (self->config)
|
||||
gst_structure_free (self->config);
|
||||
g_mutex_clear (&self->lock);
|
||||
g_cond_clear (&self->cond);
|
||||
|
||||
|
@ -2488,6 +2531,26 @@ mute_notify_cb (G_GNUC_UNUSED GObject * obj, G_GNUC_UNUSED GParamSpec * pspec,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
source_setup_cb (GstElement * playbin, GstElement * source, GstPlayer * self)
|
||||
{
|
||||
gchar *user_agent;
|
||||
|
||||
user_agent = gst_player_config_get_user_agent (self->config);
|
||||
if (user_agent) {
|
||||
GParamSpec *prop;
|
||||
|
||||
prop = g_object_class_find_property (G_OBJECT_GET_CLASS (source),
|
||||
"user-agent");
|
||||
if (prop && prop->value_type == G_TYPE_STRING) {
|
||||
GST_INFO_OBJECT (self, "Setting source user-agent: %s", user_agent);
|
||||
g_object_set (source, "user-agent", user_agent, NULL);
|
||||
}
|
||||
|
||||
g_free (user_agent);
|
||||
}
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_player_main (gpointer data)
|
||||
{
|
||||
|
@ -2577,6 +2640,8 @@ gst_player_main (gpointer data)
|
|||
G_CALLBACK (volume_notify_cb), self);
|
||||
g_signal_connect (self->playbin, "notify::mute",
|
||||
G_CALLBACK (mute_notify_cb), self);
|
||||
g_signal_connect (self->playbin, "source-setup",
|
||||
G_CALLBACK (source_setup_cb), self);
|
||||
|
||||
self->target_state = GST_STATE_NULL;
|
||||
self->current_state = GST_STATE_NULL;
|
||||
|
@ -4061,3 +4126,104 @@ gst_player_error_get_name (GstPlayerError error)
|
|||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_player_set_config:
|
||||
* @player: #GstPlayer instance
|
||||
* @config: (transfer full): a #GstStructure
|
||||
*
|
||||
* Set the configuration of the player. If the player is already configured, and
|
||||
* the configuration haven't change, this function will return %TRUE. If the
|
||||
* player is not in the GST_PLAYER_STATE_STOPPED, this method will return %FALSE
|
||||
* and active configuration will remain.
|
||||
*
|
||||
* @config is a #GstStructure that contains the configuration parameters for
|
||||
* the player.
|
||||
*
|
||||
* This function takes ownership of @config.
|
||||
*
|
||||
* Returns: %TRUE when the configuration could be set.
|
||||
* Since 1.10
|
||||
*/
|
||||
gboolean
|
||||
gst_player_set_config (GstPlayer * self, GstStructure * config)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_PLAYER (self), FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
if (self->app_state != GST_PLAYER_STATE_STOPPED) {
|
||||
GST_INFO_OBJECT (self, "can't change config while player is %s",
|
||||
gst_player_state_get_name (self->app_state));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (self->config)
|
||||
gst_structure_free (self->config);
|
||||
self->config = config;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_player_get_config:
|
||||
* @player: #GstPlayer instance
|
||||
*
|
||||
* Get a copy of the current configuration of the player. This configuration
|
||||
* can either be modified and used for the gst_player_set_config() call
|
||||
* or it must be freed after usage.
|
||||
*
|
||||
* Returns: (transfer full): a copy of the current configuration of @player. Use
|
||||
* gst_structure_free() after usage or gst_player_set_config().
|
||||
* Since 1.10
|
||||
*/
|
||||
GstStructure *
|
||||
gst_player_get_config (GstPlayer * self)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_PLAYER (self), NULL);
|
||||
|
||||
return gst_structure_copy (self->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_player_config_set_user_agent:
|
||||
* @config: a #GstPlayer configuration
|
||||
* @agent: the string to use as user agent
|
||||
*
|
||||
* Set the user agent to pass to the server if @player needs to connect
|
||||
* to a server during playback. This is typically used when playing HTTP
|
||||
* or RTSP streams.
|
||||
*
|
||||
* Since 1.10
|
||||
*/
|
||||
void
|
||||
gst_player_config_set_user_agent (GstStructure * config, const gchar * agent)
|
||||
{
|
||||
g_return_if_fail (config != NULL);
|
||||
g_return_if_fail (agent != NULL);
|
||||
|
||||
gst_structure_id_set (config,
|
||||
CONFIG_QUARK (USER_AGENT), G_TYPE_STRING, agent, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_player_config_get_user_agent:
|
||||
* @config: a #GstPlayer configuration
|
||||
*
|
||||
* Return the user agent which has been configured using
|
||||
* gst_player_config_set_user_agent() if any.
|
||||
*
|
||||
* Returns: (transfer full): the configured agent, or %NULL
|
||||
* Since 1.10
|
||||
*/
|
||||
gchar *
|
||||
gst_player_config_get_user_agent (GstStructure * config)
|
||||
{
|
||||
gchar *agent = NULL;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
gst_structure_id_get (config,
|
||||
CONFIG_QUARK (USER_AGENT), G_TYPE_STRING, &agent, NULL);
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
|
|
@ -192,6 +192,16 @@ gint64 gst_player_get_audio_video_offset (GstPlayer * player);
|
|||
void gst_player_set_audio_video_offset (GstPlayer * player,
|
||||
gint64 offset);
|
||||
|
||||
gboolean gst_player_set_config (GstPlayer * player,
|
||||
GstStructure * config);
|
||||
GstStructure * gst_player_get_config (GstPlayer * player);
|
||||
|
||||
/* helpers for configuring the config structure */
|
||||
|
||||
void gst_player_config_set_user_agent (GstStructure * config,
|
||||
const gchar * agent);
|
||||
gchar * gst_player_config_get_user_agent (GstStructure * config);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_PLAYER_H__ */
|
||||
|
|
|
@ -1612,6 +1612,58 @@ START_TEST (test_restart)
|
|||
|
||||
END_TEST;
|
||||
|
||||
#define TEST_USER_AGENT "test user agent"
|
||||
|
||||
static void
|
||||
source_setup_cb (GstElement * playbin, GstElement * source, GMainLoop * loop)
|
||||
{
|
||||
gchar *user_agent;
|
||||
|
||||
g_object_get (source, "user-agent", &user_agent, NULL);
|
||||
fail_unless_equals_string (user_agent, TEST_USER_AGENT);
|
||||
g_free (user_agent);
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
START_TEST (test_user_agent)
|
||||
{
|
||||
GstPlayer *player;
|
||||
GMainLoop *loop;
|
||||
GstElement *pipeline;
|
||||
GstStructure *config;
|
||||
gchar *user_agent;
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
player = gst_player_new (NULL, NULL);
|
||||
fail_unless (player != NULL);
|
||||
|
||||
gst_player_set_uri (player, "http://badger.com/test.mkv");
|
||||
|
||||
config = gst_player_get_config (player);
|
||||
gst_player_config_set_user_agent (config, TEST_USER_AGENT);
|
||||
|
||||
user_agent = gst_player_config_get_user_agent (config);
|
||||
fail_unless_equals_string (user_agent, TEST_USER_AGENT);
|
||||
g_free (user_agent);
|
||||
|
||||
gst_player_set_config (player, config);
|
||||
|
||||
pipeline = gst_player_get_pipeline (player);
|
||||
g_signal_connect (pipeline, "source-setup", G_CALLBACK (source_setup_cb),
|
||||
loop);
|
||||
|
||||
gst_player_pause (player);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
gst_object_unref (pipeline);
|
||||
|
||||
g_object_unref (player);
|
||||
g_main_loop_unref (loop);
|
||||
}
|
||||
|
||||
END_TEST;
|
||||
|
||||
static Suite *
|
||||
player_suite (void)
|
||||
{
|
||||
|
@ -1654,6 +1706,7 @@ player_suite (void)
|
|||
tcase_add_test (tc_general, test_play_backward_rate);
|
||||
tcase_add_test (tc_general, test_play_audio_video_seek_done);
|
||||
tcase_add_test (tc_general, test_restart);
|
||||
tcase_add_test (tc_general, test_user_agent);
|
||||
|
||||
suite_add_tcase (s, tc_general);
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ EXPORTS
|
|||
gst_player_audio_info_get_type
|
||||
gst_player_color_balance_type_get_name
|
||||
gst_player_color_balance_type_get_type
|
||||
gst_player_config_get_user_agent
|
||||
gst_player_config_set_user_agent
|
||||
gst_player_error_get_name
|
||||
gst_player_error_get_type
|
||||
gst_player_error_quark
|
||||
|
@ -15,6 +17,7 @@ EXPORTS
|
|||
gst_player_get_audio_streams
|
||||
gst_player_get_audio_video_offset
|
||||
gst_player_get_color_balance
|
||||
gst_player_get_config
|
||||
gst_player_get_current_audio_track
|
||||
gst_player_get_current_subtitle_track
|
||||
gst_player_get_current_video_track
|
||||
|
@ -53,6 +56,7 @@ EXPORTS
|
|||
gst_player_set_audio_track_enabled
|
||||
gst_player_set_audio_video_offset
|
||||
gst_player_set_color_balance
|
||||
gst_player_set_config
|
||||
gst_player_set_multiview_flags
|
||||
gst_player_set_multiview_mode
|
||||
gst_player_set_mute
|
||||
|
|
Loading…
Reference in a new issue