Original commit message from CVS: Code cleanup, make it adhere to the Gnome/Gtk+ code formatting, which is quite clean and more readable. Renamed parseavi to avidecoder Implemented seeking/time display/pause/play/stop/clean exit to gstmediaplay Added an element flag to indicate that it cannot deal with noncontigous buffers. If such an element is found in the pipeline, seeking is disabled for the complete stream (avidecoder cannot deal with seeking until we convert it to a loop based element with pull_region to fetch the indeces etc...)
423 lines
12 KiB
C
423 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));
|
|
|
|
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);
|
|
}
|
|
|
|
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) {
|
|
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;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
gst_play_play (play->play);
|
|
update_buttons (play, GST_PLAY_STATE(play->play));
|
|
}
|
|
|
|
void
|
|
on_toggle_pause_toggled (GtkToggleButton *togglebutton,
|
|
GstMediaPlay *play)
|
|
{
|
|
gst_play_pause (play->play);
|
|
update_buttons (play, GST_PLAY_STATE(play->play));
|
|
}
|
|
|
|
void
|
|
on_toggle_stop_toggled (GtkToggleButton *togglebutton,
|
|
GstMediaPlay *play)
|
|
{
|
|
gst_play_stop (play->play);
|
|
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);
|
|
}
|
|
|