mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-14 05:12:09 +00:00
dbe262dfbb
Original commit message from CVS: Make sure the Gdk thread lock is not held inside the gstreamer pipeline. Fix the videosink to not hold the Gdk lock when emitting a signal. All Gtk GUI apps using GStreamer should now handle the Gdk locks when handling signals from the pipeline (as it should be)
433 lines
12 KiB
C
433 lines
12 KiB
C
/*
|
|
* Initial main.c file generated by Glade. Edit as required.
|
|
* Glade will not overwrite this file.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <gnome.h>
|
|
#include "gstmediaplay.h"
|
|
#include "callbacks.h"
|
|
|
|
static void gst_media_play_class_init (GstMediaPlayClass *klass);
|
|
static void gst_media_play_init (GstMediaPlay *play);
|
|
|
|
static void gst_media_play_set_arg (GtkObject *object,GtkArg *arg,guint id);
|
|
static void gst_media_play_get_arg (GtkObject *object,GtkArg *arg,guint id);
|
|
|
|
static void gst_media_play_frame_displayed (GstPlay *play, GstMediaPlay *mplay);
|
|
static void gst_media_play_state_changed (GstPlay *play, GstPlayState state, GstMediaPlay *mplay);
|
|
static void gst_media_play_slider_changed (GtkAdjustment *adj, GstMediaPlay *mplay);
|
|
|
|
static void update_buttons (GstMediaPlay *mplay, GstPlayState state);
|
|
static void update_slider (GstMediaPlay *mplay, GtkAdjustment *adjustment, gfloat value);
|
|
|
|
/* signals and args */
|
|
enum {
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
enum {
|
|
ARG_0,
|
|
};
|
|
|
|
static void
|
|
target_drag_data_received (GtkWidget *widget,
|
|
GdkDragContext *context,
|
|
gint x,
|
|
gint y,
|
|
GtkSelectionData *data,
|
|
guint info,
|
|
guint time)
|
|
{
|
|
if (strstr (data->data, "file:")) {
|
|
g_print ("Got: %s\n",data->data);
|
|
}
|
|
}
|
|
|
|
static GtkTargetEntry target_table[] = {
|
|
{ "text/plain", 0, 0 }
|
|
};
|
|
|
|
static GtkObject *parent_class = NULL;
|
|
//static guint gst_media_play_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
GtkType
|
|
gst_media_play_get_type(void)
|
|
{
|
|
static GtkType play_type = 0;
|
|
|
|
if (!play_type) {
|
|
static const GtkTypeInfo play_info = {
|
|
"GstMediaPlay",
|
|
sizeof(GstMediaPlay),
|
|
sizeof(GstMediaPlayClass),
|
|
(GtkClassInitFunc)gst_media_play_class_init,
|
|
(GtkObjectInitFunc)gst_media_play_init,
|
|
NULL,
|
|
NULL,
|
|
(GtkClassInitFunc)NULL,
|
|
};
|
|
play_type = gtk_type_unique(gtk_object_get_type(),&play_info);
|
|
}
|
|
return play_type;
|
|
}
|
|
|
|
static void
|
|
gst_media_play_class_init (GstMediaPlayClass *klass)
|
|
{
|
|
GtkObjectClass *object_class;
|
|
|
|
parent_class = gtk_type_class (gtk_object_get_type ());
|
|
|
|
object_class = (GtkObjectClass*)klass;
|
|
|
|
object_class->set_arg = gst_media_play_set_arg;
|
|
object_class->get_arg = gst_media_play_get_arg;
|
|
}
|
|
|
|
typedef struct {
|
|
GstMediaPlay *play;
|
|
GModule *symbols;
|
|
} connect_struct;
|
|
|
|
/* we need more control here so... */
|
|
static void
|
|
gst_media_play_connect_func (const gchar *handler_name,
|
|
GtkObject *object,
|
|
const gchar *signal_name,
|
|
const gchar *signal_data,
|
|
GtkObject *connect_object,
|
|
gboolean after,
|
|
gpointer user_data)
|
|
{
|
|
GtkSignalFunc func;
|
|
connect_struct *data = (connect_struct *)user_data;
|
|
|
|
if (!g_module_symbol (data->symbols, handler_name, (gpointer *)&func))
|
|
g_warning("gsteditorproperty: could not find signal handler '%s'.", handler_name);
|
|
else {
|
|
if (after)
|
|
gtk_signal_connect_after (object, signal_name, func, (gpointer) data->play);
|
|
else
|
|
gtk_signal_connect (object, signal_name, func, (gpointer) data->play);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
gst_media_play_init(GstMediaPlay *mplay)
|
|
{
|
|
GtkWidget *gstplay;
|
|
GModule *symbols;
|
|
connect_struct data;
|
|
|
|
glade_init();
|
|
glade_gnome_init();
|
|
|
|
g_print("using %s\n", DATADIR"gstmediaplay.glade");
|
|
/* load the interface */
|
|
mplay->xml = glade_xml_new (DATADIR "gstmediaplay.glade", "gstplay");
|
|
|
|
mplay->slider = glade_xml_get_widget(mplay->xml, "slider");
|
|
{
|
|
GtkArg arg;
|
|
GtkRange *range;
|
|
|
|
arg.name = "adjustment";
|
|
gtk_object_getv (GTK_OBJECT (mplay->slider), 1, &arg);
|
|
range = GTK_RANGE (GTK_VALUE_POINTER (arg));
|
|
mplay->adjustment = gtk_range_get_adjustment (range);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (mplay->adjustment), "value_changed",
|
|
GTK_SIGNAL_FUNC (gst_media_play_slider_changed), mplay);
|
|
}
|
|
|
|
mplay->play_button = glade_xml_get_widget (mplay->xml, "toggle_play");
|
|
mplay->pause_button = glade_xml_get_widget (mplay->xml, "toggle_pause");
|
|
mplay->stop_button = glade_xml_get_widget (mplay->xml, "toggle_stop");
|
|
|
|
gstplay = glade_xml_get_widget (mplay->xml, "gstplay");
|
|
gtk_drag_dest_set (gstplay,
|
|
GTK_DEST_DEFAULT_ALL,
|
|
target_table, 1,
|
|
GDK_ACTION_COPY);
|
|
gtk_signal_connect (GTK_OBJECT (gstplay), "drag_data_received",
|
|
GTK_SIGNAL_FUNC (target_drag_data_received),
|
|
NULL);
|
|
|
|
mplay->play = gst_play_new();
|
|
|
|
gtk_signal_connect (GTK_OBJECT (mplay->play), "frame_displayed",
|
|
GTK_SIGNAL_FUNC (gst_media_play_frame_displayed),
|
|
mplay);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (mplay->play), "audio_played",
|
|
GTK_SIGNAL_FUNC (gst_media_play_frame_displayed),
|
|
mplay);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (mplay->play), "playing_state_changed",
|
|
GTK_SIGNAL_FUNC (gst_media_play_state_changed),
|
|
mplay);
|
|
|
|
gnome_dock_set_client_area (GNOME_DOCK (glade_xml_get_widget(mplay->xml, "dock1")),
|
|
GTK_WIDGET (mplay->play));
|
|
|
|
gtk_widget_show (GTK_WIDGET (mplay->play));
|
|
|
|
mplay->status = gst_status_area_new();
|
|
gst_status_area_set_state (mplay->status, GST_STATUS_AREA_STATE_INIT);
|
|
gst_status_area_set_playtime (mplay->status, "00:00 / 00:00");
|
|
|
|
symbols = g_module_open (NULL, 0);
|
|
|
|
data.play = mplay;
|
|
data.symbols = symbols;
|
|
|
|
glade_xml_signal_autoconnect_full (mplay->xml, gst_media_play_connect_func, &data);
|
|
|
|
gtk_container_add (GTK_CONTAINER (glade_xml_get_widget (mplay->xml, "dockitem4")),
|
|
GTK_WIDGET (mplay->status));
|
|
gtk_widget_show (GTK_WIDGET (mplay->status));
|
|
|
|
mplay->last_time = 0;
|
|
}
|
|
|
|
GstMediaPlay *
|
|
gst_media_play_new ()
|
|
{
|
|
return GST_MEDIA_PLAY (gtk_type_new (GST_TYPE_MEDIA_PLAY));
|
|
}
|
|
|
|
static void
|
|
gst_media_play_update_status_area (GstMediaPlay *play,
|
|
gulong current_time,
|
|
gulong total_time)
|
|
{
|
|
gst_status_area_set_playtime (play->status,
|
|
g_strdup_printf("%02lu:%02lu / %02lu:%02lu",
|
|
current_time/60, current_time%60,
|
|
total_time/60, total_time%60));
|
|
}
|
|
|
|
void
|
|
gst_media_play_start_uri (GstMediaPlay *play,
|
|
const guchar *uri)
|
|
{
|
|
GstPlayReturn ret;
|
|
|
|
g_return_if_fail (play != NULL);
|
|
g_return_if_fail (GST_IS_MEDIA_PLAY (play));
|
|
|
|
if (uri != NULL) {
|
|
ret = gst_play_set_uri (play->play, uri);
|
|
|
|
if (!gst_play_media_can_seek (play->play)) {
|
|
gtk_widget_set_sensitive (play->slider, FALSE);
|
|
}
|
|
|
|
gst_play_play (play->play);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gst_media_play_set_arg (GtkObject *object,
|
|
GtkArg *arg,
|
|
guint id)
|
|
{
|
|
GstMediaPlay *play;
|
|
play = GST_MEDIA_PLAY (object);
|
|
|
|
switch (id) {
|
|
default:
|
|
g_warning("GstMediaPlay: unknown arg!");
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gst_media_play_get_arg (GtkObject *object,
|
|
GtkArg *arg,
|
|
guint id)
|
|
{
|
|
GstMediaPlay *play;
|
|
|
|
play = GST_MEDIA_PLAY (object);
|
|
|
|
switch (id) {
|
|
default:
|
|
arg->type = GTK_TYPE_INVALID;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gst_media_play_state_changed (GstPlay *play,
|
|
GstPlayState state,
|
|
GstMediaPlay *mplay)
|
|
{
|
|
GstStatusAreaState area_state;
|
|
|
|
g_return_if_fail (GST_IS_PLAY (play));
|
|
g_return_if_fail (GST_IS_MEDIA_PLAY (mplay));
|
|
|
|
|
|
gdk_threads_enter ();
|
|
update_buttons (mplay, state);
|
|
|
|
switch (state) {
|
|
case GST_PLAY_STOPPED:
|
|
area_state = GST_STATUS_AREA_STATE_STOPPED;
|
|
break;
|
|
case GST_PLAY_PLAYING:
|
|
area_state = GST_STATUS_AREA_STATE_PLAYING;
|
|
break;
|
|
case GST_PLAY_PAUSED:
|
|
area_state = GST_STATUS_AREA_STATE_PAUSED;
|
|
break;
|
|
default:
|
|
area_state = GST_STATUS_AREA_STATE_INIT;
|
|
}
|
|
gst_status_area_set_state (mplay->status, area_state);
|
|
gdk_threads_leave ();
|
|
}
|
|
|
|
void
|
|
on_gst_media_play_destroy (GtkWidget *widget,
|
|
GstMediaPlay *mplay)
|
|
{
|
|
gst_main_quit ();
|
|
}
|
|
|
|
gint
|
|
on_gst_media_play_delete_event (GtkWidget *widget,
|
|
GdkEvent *event,
|
|
GstMediaPlay *mplay)
|
|
{
|
|
gdk_threads_leave ();
|
|
gst_play_stop (mplay->play);
|
|
gdk_threads_enter ();
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gst_media_play_frame_displayed (GstPlay *play,
|
|
GstMediaPlay *mplay)
|
|
{
|
|
gulong current_time;
|
|
gulong total_time;
|
|
gulong size, current_offset;
|
|
|
|
g_return_if_fail (GST_IS_PLAY (play));
|
|
g_return_if_fail (GST_IS_MEDIA_PLAY (mplay));
|
|
|
|
current_time = gst_play_get_media_current_time (play);
|
|
total_time = gst_play_get_media_total_time (play);
|
|
size = gst_play_get_media_size (play);
|
|
current_offset = gst_play_get_media_offset (play);
|
|
|
|
if (current_time != mplay->last_time) {
|
|
gdk_threads_enter ();
|
|
gst_media_play_update_status_area (mplay, current_time, total_time);
|
|
update_slider (mplay, mplay->adjustment, current_offset*100.0/size);
|
|
mplay->last_time = current_time;
|
|
gdk_threads_leave ();
|
|
}
|
|
}
|
|
|
|
static void
|
|
gst_media_play_slider_changed (GtkAdjustment *adj,
|
|
GstMediaPlay *mplay)
|
|
{
|
|
gulong size;
|
|
|
|
g_return_if_fail (GST_IS_MEDIA_PLAY (mplay));
|
|
|
|
size = gst_play_get_media_size (mplay->play);
|
|
|
|
gst_play_media_seek(mplay->play, (int)(adj->value*size/100.0));
|
|
}
|
|
|
|
void
|
|
on_toggle_play_toggled (GtkToggleButton *togglebutton,
|
|
GstMediaPlay *play)
|
|
{
|
|
gdk_threads_leave ();
|
|
gst_play_play (play->play);
|
|
gdk_threads_enter ();
|
|
update_buttons (play, GST_PLAY_STATE(play->play));
|
|
}
|
|
|
|
void
|
|
on_toggle_pause_toggled (GtkToggleButton *togglebutton,
|
|
GstMediaPlay *play)
|
|
{
|
|
gdk_threads_leave ();
|
|
gst_play_pause (play->play);
|
|
gdk_threads_enter ();
|
|
update_buttons (play, GST_PLAY_STATE(play->play));
|
|
}
|
|
|
|
void
|
|
on_toggle_stop_toggled (GtkToggleButton *togglebutton,
|
|
GstMediaPlay *play)
|
|
{
|
|
gdk_threads_leave ();
|
|
gst_play_stop (play->play);
|
|
gdk_threads_enter ();
|
|
update_buttons (play, GST_PLAY_STATE(play->play));
|
|
}
|
|
|
|
static void
|
|
update_buttons (GstMediaPlay *mplay,
|
|
GstPlayState state)
|
|
{
|
|
gtk_signal_handler_block_by_func (GTK_OBJECT (mplay->play_button),
|
|
GTK_SIGNAL_FUNC (on_toggle_play_toggled),
|
|
mplay);
|
|
gtk_signal_handler_block_by_func (GTK_OBJECT (mplay->pause_button),
|
|
GTK_SIGNAL_FUNC (on_toggle_pause_toggled),
|
|
mplay);
|
|
gtk_signal_handler_block_by_func (GTK_OBJECT (mplay->stop_button),
|
|
GTK_SIGNAL_FUNC (on_toggle_stop_toggled),
|
|
mplay);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->play_button), FALSE);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->pause_button), FALSE);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->stop_button), FALSE);
|
|
|
|
if (state == GST_PLAY_PLAYING) {
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->play_button), TRUE);
|
|
}
|
|
else if (state == GST_PLAY_PAUSED) {
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->pause_button), TRUE);
|
|
}
|
|
else if (state == GST_PLAY_STOPPED) {
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mplay->stop_button), TRUE);
|
|
}
|
|
|
|
gtk_signal_handler_unblock_by_func (GTK_OBJECT (mplay->play_button),
|
|
GTK_SIGNAL_FUNC (on_toggle_play_toggled),
|
|
mplay);
|
|
gtk_signal_handler_unblock_by_func (GTK_OBJECT (mplay->pause_button),
|
|
GTK_SIGNAL_FUNC (on_toggle_pause_toggled),
|
|
mplay);
|
|
gtk_signal_handler_unblock_by_func (GTK_OBJECT (mplay->stop_button),
|
|
GTK_SIGNAL_FUNC (on_toggle_stop_toggled),
|
|
mplay);
|
|
}
|
|
|
|
static void
|
|
update_slider (GstMediaPlay *mplay,
|
|
GtkAdjustment *adjustment,
|
|
gfloat value)
|
|
{
|
|
gtk_signal_handler_block_by_func (GTK_OBJECT (adjustment),
|
|
GTK_SIGNAL_FUNC (gst_media_play_slider_changed),
|
|
mplay);
|
|
gtk_adjustment_set_value (adjustment, value);
|
|
gtk_signal_handler_unblock_by_func (GTK_OBJECT (adjustment),
|
|
GTK_SIGNAL_FUNC (gst_media_play_slider_changed),
|
|
mplay);
|
|
}
|
|
|