Misc fixes and cleanups

Original commit message from CVS:
Misc fixes and cleanups
A reworked gstplay. Now it is called gstmediaplay. gstplay is a custom
widget that can display media and is to become a bonobo component soon.
put the tables of the mpeg audio encoder in a header file.
maybe faster quantisation for the mpeg encoder.
This commit is contained in:
Wim Taymans 2000-10-30 21:02:08 +00:00
parent 31cae4b447
commit 4a38cd655b
22 changed files with 1237 additions and 434 deletions

View file

@ -57,8 +57,12 @@ static void gst_queue_init(GstQueue *queue);
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_queue_get_arg(GtkObject *object,GtkArg *arg,guint id);
void gst_queue_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf);
static void gst_queue_push(GstConnection *connection);
static void gst_queue_chain(GstPad *pad,GstBuffer *buf);
static void gst_queue_flush(GstQueue *queue);
static GstElementStateReturn gst_queue_change_state(GstElement *element);
static GstConnectionClass *parent_class = NULL;
//static guint gst_queue_signals[LAST_SIGNAL] = { 0 };
@ -85,9 +89,11 @@ gst_queue_get_type(void) {
static void gst_queue_class_init(GstQueueClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstConnectionClass *gstconnection_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstconnection_class = (GstConnectionClass*)klass;
parent_class = gtk_type_class(GST_TYPE_CONNECTION);
@ -101,6 +107,8 @@ static void gst_queue_class_init(GstQueueClass *klass) {
gtkobject_class->set_arg = gst_queue_set_arg;
gtkobject_class->get_arg = gst_queue_get_arg;
gstelement_class->change_state = gst_queue_change_state;
}
static void gst_queue_init(GstQueue *queue) {
@ -137,7 +145,14 @@ static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
gst_buffer_unref(GST_BUFFER(data));
}
void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
static void gst_queue_flush(GstQueue *queue) {
g_slist_foreach(queue->queue, gst_queue_cleanup_buffers, gst_element_get_name(GST_ELEMENT(queue)));
g_slist_free(queue->queue);
queue->queue = NULL;
queue->level_buffers = 0;
}
static void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
GstQueue *queue;
gboolean tosignal = FALSE;
guchar *name;
@ -157,13 +172,9 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
DEBUG("queue: have queue lock\n");
if (GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLUSH)) {
g_slist_foreach(queue->queue, gst_queue_cleanup_buffers, name);
g_slist_free(queue->queue);
queue->queue = NULL;
queue->level_buffers = 0;
gst_queue_flush(queue);
}
DEBUG("queue: %s: chain %d %p\n", name, queue->level_buffers, buf);
while (queue->level_buffers >= queue->max_buffers) {
@ -199,7 +210,7 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
}
}
void gst_queue_push(GstConnection *connection) {
static void gst_queue_push(GstConnection *connection) {
GstQueue *queue = GST_QUEUE(connection);
GstBuffer *buf = NULL;
GSList *front;
@ -248,6 +259,26 @@ void gst_queue_push(GstConnection *connection) {
/* unlock now */
}
static GstElementStateReturn gst_queue_change_state(GstElement *element) {
GstQueue *queue;
g_return_val_if_fail(GST_IS_QUEUE(element),GST_STATE_FAILURE);
queue = GST_QUEUE(element);
DEBUG("gstqueue: state pending %d\n", GST_STATE_PENDING(element));
/* if going down into NULL state, clear out buffers*/
if (GST_STATE_PENDING(element) == GST_STATE_READY) {
/* otherwise (READY or higher) we need to open the file */
gst_queue_flush(queue);
}
/* if we haven't failed already, give the parent class a chance to ;-) */
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element);
return GST_STATE_SUCCESS;
}
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstQueue *queue;

View file

@ -720,7 +720,7 @@ void gst_bin_iterate_func(GstBin *bin) {
gst_element_get_name(GST_ELEMENT(bin->children->data)));
} else {
if (bin->numentries <= 0) {
printf("gstbin: no entries in bin \"%s\" trying children...\n", gst_element_get_name(GST_ELEMENT(bin)));
//printf("gstbin: no entries in bin \"%s\" trying children...\n", gst_element_get_name(GST_ELEMENT(bin)));
// we will try loop over the elements then...
entries = bin->children;
}

View file

@ -170,6 +170,7 @@ GstElement *gst_thread_new(guchar *name) {
thread = gtk_type_new(gst_thread_get_type());
gst_element_set_name(GST_ELEMENT(thread),name);
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
return GST_ELEMENT(thread);
}
@ -205,7 +206,6 @@ static GstElementStateReturn gst_thread_change_state(GstElement *element) {
// set the state to idle
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
// create the thread if that's what we're supposed to do
gst_info("gstthread: flags are 0x%08x\n",GST_FLAGS(thread));
if (GST_FLAG_IS_SET(thread,GST_THREAD_CREATE)) {
@ -224,14 +224,12 @@ static GstElementStateReturn gst_thread_change_state(GstElement *element) {
gst_info("gstthread: starting thread \"%s\"\n",
gst_element_get_name(GST_ELEMENT(element)));
GST_FLAG_SET(thread,GST_THREAD_STATE_SPINNING);
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
gst_thread_signal_thread(thread);
break;
case GST_STATE_PAUSED:
gst_info("gstthread: pausing thread \"%s\"\n",
gst_element_get_name(GST_ELEMENT(element)));
GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
gst_thread_signal_thread(thread);
break;
case GST_STATE_NULL:

2
gstplay/.gitignore vendored
View file

@ -5,4 +5,4 @@ Makefile.in
*.la
.deps
.libs
gstplay
gstmediaplay

View file

@ -4,21 +4,24 @@ INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) \
$(shell gnome-config --cflags gnomeui) $(shell gstreamer-config --cflags)
bin_PROGRAMS = gstplay
bin_PROGRAMS = gstmediaplay
gladedir = $(datadir)/gstplay
glade_DATA = gstplay.glade play.xpm stop.xpm pause.xpm
gladedir = $(datadir)/gstmediaplay
glade_DATA = gstmediaplay.glade play.xpm stop.xpm pause.xpm
gstplay_SOURCES = \
gstplay.c \
interface.c interface.h \
callbacks.c callbacks.h
gstmediaplay_SOURCES = \
gstplay.c main.c \
gstmediaplay.c gstmediaplay.h \
gststatusarea.c gststatusarea.h \
callbacks.c callbacks.h
# interface.c interface.h
CFLAGS += -O2 -Wall -DDATADIR=\""$(gladedir)/"\"
gstplay_CFLAGS = $(shell gnome-config --cflags gnomeui) $(shell libglade-config --cflags gnome) \
gstmediaplay_CFLAGS = $(shell gnome-config --cflags gnomeui) $(shell libglade-config --cflags gnome) \
$(shell gstreamer-config --cflags )
gstplay_LDFLAGS = $(shell gnome-config --libs gnomeui) $(shell libglade-config --libs gnome) \
gstmediaplay_LDFLAGS = $(shell gnome-config --libs gnomeui) $(shell libglade-config --libs gnome) \
$(shell gstreamer-config --libs )
if HAVE_LIBXV
@ -27,7 +30,7 @@ else
xvlibs=
endif
gstplay_LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la \
gstmediaplay_LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la \
$(top_builddir)/plugins/videosink/gdkxvimage.lo ${xvlibs} -lXxf86vm

View file

@ -10,12 +10,7 @@
#include "callbacks.h"
#include "interface.h"
extern GstElement *src;
extern gboolean picture_shown;
extern GstPlayState state;
extern guchar statusline[];
extern guchar *statustext;
extern GtkFileSelection *open_file_selection;
GtkFileSelection *open_file_selection;
void
on_save1_activate (GtkMenuItem *menuitem,
@ -53,75 +48,35 @@ on_open2_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GladeXML *xml;
xml = glade_xml_new(DATADIR "gstplay.glade", "fileselection1");
xml = glade_xml_new(DATADIR "gstmediaplay.glade", "fileselection1");
/* connect the signals in the interface */
glade_xml_signal_autoconnect(xml);
open_file_selection = glade_xml_get_widget(xml, "fileselection1");
}
void
on_toggle_play_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
update_buttons(0);
change_state(GSTPLAY_PLAYING);
}
void
on_toggle_pause_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
update_buttons(1);
change_state(GSTPLAY_PAUSE);
}
void
on_toggle_stop_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
update_buttons(2);
change_state(GSTPLAY_STOPPED);
open_file_selection = GTK_FILE_SELECTION(glade_xml_get_widget(xml, "fileselection1"));
}
void
on_hscale1_value_changed (GtkAdjustment *adj,
gpointer user_data)
{
int size = gst_util_get_int_arg(GTK_OBJECT(src),"size");
//int size = gst_util_get_int_arg(GTK_OBJECT(src),"size");
gtk_object_set(GTK_OBJECT(src),"offset",(int)(adj->value*size/100.0),NULL);
//gtk_object_set(GTK_OBJECT(src),"offset",(int)(adj->value*size/100.0),NULL);
if (state != GSTPLAY_PLAYING) {
show_next_picture();
}
}
void
on_drawingarea1_configure_event (GtkWidget *widget, GdkEventConfigure *event,
gpointer user_data)
{
gdk_draw_rectangle(widget->window,
widget->style->black_gc,
TRUE, 0,0,
widget->allocation.width,
widget->allocation.height);
gdk_draw_string(widget->window,widget->style->font,widget->style->white_gc, 8, 15, statustext);
gdk_draw_string(widget->window,widget->style->font,widget->style->white_gc, widget->allocation.width-100, 15, statusline);
//if (state != GSTPLAY_PLAYING) {
// show_next_picture();
//}
}
void on_about_activate(GtkWidget *widget, gpointer data)
{
GladeXML *xml;
xml = glade_xml_new(DATADIR "gstplay.glade", "about");
xml = glade_xml_new(DATADIR "gstmediaplay.glade", "about");
/* connect the signals in the interface */
glade_xml_signal_autoconnect(xml);
}
void on_gstplay_destroy(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
gst_main_quit();
}

View file

@ -40,14 +40,3 @@ void
on_drawingarea1_configure_event (GtkWidget *widget, GdkEventConfigure *event,
gpointer user_data);
void
on_toggle_play_toggled (GtkToggleButton *togglebutton,
gpointer user_data);
void
on_toggle_pause_toggled (GtkToggleButton *togglebutton,
gpointer user_data);
void
on_toggle_stop_toggled (GtkToggleButton *togglebutton,
gpointer user_data);

View file

@ -1,12 +0,0 @@
/* mpeg1.c */
void mpeg1_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline);
void mpeg1_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline);
void mpeg1_setup_audio_thread(GstPad *pad, GstElement *show, GstElement *pipeline);
/* mpeg2.c */
void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline);
void mpeg2_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline);
/* avi.c */
void avi_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline);

297
gstplay/gstmediaplay.c Normal file
View file

@ -0,0 +1,297 @@
/*
* 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 update_buttons (GstMediaPlay *mplay, GstPlayState state);
static void update_slider (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->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();
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));
}
GstMediaPlay *
gst_media_play_new ()
{
return GST_MEDIA_PLAY (gtk_type_new (GST_TYPE_MEDIA_PLAY));
}
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);
gst_status_area_set_state (play->status, GST_STATUS_AREA_STATE_PLAYING);
gst_play_play (play->play);
update_buttons (play, GST_PLAY_STATE (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;
}
}
void
on_toggle_play_toggled (GtkToggleButton *togglebutton,
GstMediaPlay *play)
{
gst_status_area_set_state (play->status, GST_STATUS_AREA_STATE_PLAYING);
gst_play_play (play->play);
update_buttons (play, GST_PLAY_STATE (play->play));
}
void
on_toggle_pause_toggled (GtkToggleButton *togglebutton,
GstMediaPlay *play)
{
gst_status_area_set_state (play->status, GST_STATUS_AREA_STATE_PAUSED);
gst_play_pause (play->play);
update_buttons (play, GST_PLAY_STATE (play->play));
}
void
on_toggle_stop_toggled (GtkToggleButton *togglebutton,
GstMediaPlay *play)
{
gst_status_area_set_state (play->status, GST_STATUS_AREA_STATE_STOPPED);
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 (GtkAdjustment *adjustment,
gfloat value)
{
gtk_signal_handler_block_by_func (GTK_OBJECT (adjustment),
GTK_SIGNAL_FUNC (on_hscale1_value_changed),
NULL);
gtk_adjustment_set_value (adjustment, value);
gtk_signal_handler_unblock_by_func (GTK_OBJECT (adjustment),
GTK_SIGNAL_FUNC (on_hscale1_value_changed),
NULL);
}

View file

@ -2,8 +2,8 @@
<GTK-Interface>
<project>
<name>Gstplay</name>
<program_name>gstplay</program_name>
<name>GstMediaPlay</name>
<program_name>gstmediaplay</program_name>
<directory></directory>
<source_directory>src</source_directory>
<pixmaps_directory>pixmaps</pixmaps_directory>
@ -369,14 +369,7 @@
<shadow_type>GTK_SHADOW_OUT</shadow_type>
<widget>
<class>GtkDrawingArea</class>
<name>status_area</name>
<height>21</height>
<signal>
<name>configure_event</name>
<handler>on_drawingarea1_configure_event</handler>
<last_modification_time>Sun, 06 Aug 2000 11:27:09 GMT</last_modification_time>
</signal>
<class>Placeholder</class>
</widget>
</widget>

55
gstplay/gstmediaplay.h Normal file
View file

@ -0,0 +1,55 @@
/*
* Initial main.c file generated by Glade. Edit as required.
* Glade will not overwrite this file.
*/
#ifndef __GST_MEDIA_PLAY_H__
#define __GST_MEDIA_PLAY_H__
#include <glade/glade.h>
#include "gstplay.h"
#include "gststatusarea.h"
typedef struct _GstMediaPlay GstMediaPlay;
typedef struct _GstMediaPlayClass GstMediaPlayClass;
#define GST_TYPE_MEDIA_PLAY \
(gst_media_play_get_type())
#define GST_MEDIA_PLAY(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_MEDIA_PLAY,GstMediaPlay))
#define GST_MEDIA_PLAY_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_MEDIA_PLAY,GstMediaPlayClass))
#define GST_IS_MEDIA_PLAY(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_MEDIA_PLAY))
#define GST_IS_MEDIA_PLAY_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_MEDIA_PLAY))
struct _GstMediaPlay {
GtkObject parent;
GladeXML *xml;
GstPlay *play;
GtkWidget *play_button;
GtkWidget *pause_button;
GtkWidget *stop_button;
GstStatusArea *status;
};
struct _GstMediaPlayClass {
GtkObjectClass parent_class;
};
GtkType gst_media_play_get_type (void);
/* setup the player */
GstMediaPlay* gst_media_play_new (void);
void gst_media_play_start_uri (GstMediaPlay *play, const guchar *uri);
#endif /* __GST_MEDIA_PLAY_H__ */

View file

@ -5,298 +5,359 @@
#include <config.h>
//#define DEBUG_ENABLED
#include <glade/glade.h>
#include <gst/gstclock.h>
#include "gstplay.h"
#include "gstplayprivate.h"
#include "callbacks.h"
#include "interface.h"
static void gst_play_class_init (GstPlayClass *klass);
static void gst_play_init (GstPlay *play);
#define MUTEX_STATUS() (g_mutex_trylock(gdk_threads_mutex)? g_mutex_unlock(gdk_threads_mutex), "was not locked" : "was locked")
static void gst_play_set_arg (GtkObject *object,GtkArg *arg,guint id);
static void gst_play_get_arg (GtkObject *object,GtkArg *arg,guint id);
#define BUFFER 20
static void gst_play_realize (GtkWidget *play);
static gboolean idle_func(gpointer data);
static gint start_from_file(guchar *filename);
static void gst_play_frame_displayed (GstElement *element, GstPlay *play);
static void gst_play_audio_handoff (GstElement *element, GstPlay *play);
GstElement *show;
GstElement *audio_play;
GstElement *src;
GstElement *parse;
GstElement *pipeline;
GstPlayState state;
gboolean picture_shown = FALSE;
guchar statusline[200];
guchar *statustext = "stopped";
GtkWidget *status_area;
GtkWidget *video;
GtkAdjustment *adjustment;
GtkWidget *play_button;
GtkWidget *pause_button;
GtkWidget *stop_button;
GtkFileSelection *open_file_selection;
static void frame_displayed(GstSrc *asrc)
{
int size, time, frame_time = 0, src_pos;
guint mux_rate;
static int prev_time = -1;
if (!parse) return;
DEBUG("gstplay: frame displayed %s\n", MUTEX_STATUS());
mux_rate = gst_util_get_int_arg(GTK_OBJECT(parse),"mux_rate");
size = gst_util_get_int_arg(GTK_OBJECT(src),"size");
time = (size*8)/mux_rate;
frame_time = gst_util_get_int_arg(GTK_OBJECT(show),"frame_time");
src_pos = gst_util_get_int_arg(GTK_OBJECT(src),"offset");
frame_time = (src_pos*8)/mux_rate;
if (frame_time >= prev_time) {
g_snprintf(statusline, 200, "%02d:%02d / %02d:%02d\n",
frame_time/60, frame_time%60,
time/60, time%60);
//printf("%d %d %g\n", frame_time, size, frame_time*100.0/size);
update_status_area(status_area);
if (state == GSTPLAY_PLAYING)
update_slider(adjustment, src_pos*100.0/size);
}
picture_shown = TRUE;
prev_time = frame_time;
DEBUG("gstplay: frame displayed end %s\n", MUTEX_STATUS());
}
static gboolean idle_func(gpointer data) {
DEBUG("idle start %s\n",MUTEX_STATUS());
gst_bin_iterate(GST_BIN(data));
DEBUG("idle stop %s\n",MUTEX_STATUS());
return TRUE;
}
static void eof(GstSrc *src) {
change_state(GSTPLAY_PAUSE);
picture_shown = TRUE;
}
void show_next_picture() {
picture_shown = FALSE;
DEBUG("gstplay: next picture %s\n", MUTEX_STATUS());
while (!picture_shown) {
gdk_threads_leave();
gst_src_push(GST_SRC(src));
gdk_threads_enter();
}
DEBUG("gstplay: next found %s\n", MUTEX_STATUS());
}
static void mute_audio(gboolean mute) {
gtk_object_set(GTK_OBJECT(audio_play),"mute",mute,NULL);
}
static void gstplay_tear_down()
{
g_print("setting to NULL state\n");
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_NULL);
}
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);
start_from_file(g_strchomp(&data->data[5]));
}
}
void
on_exit_menu_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
gdk_threads_leave();
gstplay_tear_down();
gdk_threads_enter();
gst_main_quit();
}
void on_ok_button1_clicked (GtkButton *button,
GtkFileSelection *sel)
{
gchar *selected_filename;
selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION(open_file_selection));
start_from_file(selected_filename);
}
gint on_gstplay_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
gdk_threads_leave();
gstplay_tear_down();
gdk_threads_enter();
return FALSE;
}
void change_state(GstPlayState new_state) {
if (new_state == state) return;
switch (new_state) {
case GSTPLAY_PLAYING:
mute_audio(FALSE);
statustext = "playing";
update_status_area(status_area);
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_READY);
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
gtk_idle_add(idle_func, pipeline);
state = GSTPLAY_PLAYING;
update_buttons(0);
break;
case GSTPLAY_PAUSE:
statustext = "paused";
update_status_area(status_area);
if (state != GSTPLAY_STOPPED) gtk_idle_remove_by_data(pipeline);
//gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
mute_audio(TRUE);
state = GSTPLAY_PAUSE;
update_buttons(1);
break;
case GSTPLAY_STOPPED:
if (state != GSTPLAY_PAUSE) gtk_idle_remove_by_data(pipeline);
//gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_NULL);
statustext = "stopped";
update_status_area(status_area);
mute_audio(TRUE);
state = GSTPLAY_STOPPED;
gtk_object_set(GTK_OBJECT(src),"offset",0,NULL);
update_buttons(2);
update_slider(adjustment, 0.0);
//show_next_picture();
break;
}
}
static gint start_from_file(guchar *filename)
{
src = gst_elementfactory_make("disksrc", "disk_src");
g_return_val_if_fail(src != NULL, -1);
g_print("should be using file '%s'\n",filename);
gtk_object_set(GTK_OBJECT(src),"location",filename,NULL);
gst_pipeline_add_src(GST_PIPELINE(pipeline),GST_ELEMENT(src));
gtk_signal_connect(GTK_OBJECT(src),"eos",
GTK_SIGNAL_FUNC(eof),NULL);
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("unable to handle stream\n");
exit(-1);
}
if (GST_PAD_CONNECTED(gst_element_get_pad(show, "sink"))) {
gtk_widget_show(video);
}
g_print("setting to READY state\n");
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_READY);
state = GSTPLAY_STOPPED;
change_state(GSTPLAY_PLAYING);
return 0;
}
static GtkTargetEntry target_table[] = {
{ "text/plain", 0, 0 }
/* signals and args */
enum {
SIGNAL_STATE_CHANGED,
SIGNAL_FRAME_DISPLAYED,
SIGNAL_AUDIO_PLAYED,
LAST_SIGNAL
};
int
main (int argc, char *argv[])
enum {
ARG_0,
ARG_URI,
ARG_MUTE,
ARG_STATE,
ARG_MEDIA_SIZE,
ARG_MEDIA_OFFSET,
ARG_MEDIA_TOTAL_TIME,
ARG_MEDIA_CURRENT_TIME,
};
static GtkObject *parent_class = NULL;
static guint gst_play_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_play_get_type (void)
{
GladeXML *xml;
GtkWidget *slider, *gstplay;
static GtkType play_type = 0;
bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
textdomain (PACKAGE);
gst_init(&argc,&argv);
gnome_init ("gstreamer", VERSION, argc, argv);
glade_init();
glade_gnome_init();
g_print("using %s\n", DATADIR"gstplay.glade");
/* load the interface */
xml = glade_xml_new(DATADIR "gstplay.glade", "gstplay");
status_area = glade_xml_get_widget(xml, "status_area");
slider = glade_xml_get_widget(xml, "slider");
{
GtkArg arg;
GtkRange *range;
arg.name = "adjustment";
gtk_object_getv(GTK_OBJECT(slider),1,&arg);
range = GTK_RANGE(GTK_VALUE_POINTER(arg));
adjustment = gtk_range_get_adjustment(range);
gtk_signal_connect(GTK_OBJECT(adjustment),"value_changed",
GTK_SIGNAL_FUNC(on_hscale1_value_changed),NULL);
if (!play_type) {
static const GtkTypeInfo play_info = {
"GstPlay",
sizeof(GstPlay),
sizeof(GstPlayClass),
(GtkClassInitFunc)gst_play_class_init,
(GtkObjectInitFunc)gst_play_init,
NULL,
NULL,
(GtkClassInitFunc)NULL,
};
play_type = gtk_type_unique (gtk_hbox_get_type (),&play_info);
}
return play_type;
}
static void
gst_play_class_init (GstPlayClass *klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
parent_class = gtk_type_class (gtk_hbox_get_type ());
object_class = (GtkObjectClass*)klass;
widget_class = (GtkWidgetClass*)klass;
gst_play_signals[SIGNAL_STATE_CHANGED] =
gtk_signal_new ("playing_state_changed",GTK_RUN_FIRST,object_class->type,
GTK_SIGNAL_OFFSET (GstPlayClass,state_changed),
gtk_marshal_NONE__INT,GTK_TYPE_NONE,1,
GTK_TYPE_INT);
gst_play_signals[SIGNAL_FRAME_DISPLAYED] =
gtk_signal_new ("frame_displayed",GTK_RUN_FIRST,object_class->type,
GTK_SIGNAL_OFFSET (GstPlayClass,frame_displayed),
gtk_marshal_NONE__INT,GTK_TYPE_NONE,0);
gst_play_signals[SIGNAL_AUDIO_PLAYED] =
gtk_signal_new ("audio_played",GTK_RUN_FIRST,object_class->type,
GTK_SIGNAL_OFFSET (GstPlayClass,audio_played),
gtk_marshal_NONE__INT,GTK_TYPE_NONE,0);
gtk_object_class_add_signals (object_class,gst_play_signals,LAST_SIGNAL);
gtk_object_add_arg_type ("GstPlay::uri",GTK_TYPE_STRING,
GTK_ARG_READABLE, ARG_URI);
gtk_object_add_arg_type ("GstPlay::mute",GTK_TYPE_BOOL,
GTK_ARG_READWRITE, ARG_MUTE);
gtk_object_add_arg_type ("GstPlay::state",GTK_TYPE_INT,
GTK_ARG_READABLE, ARG_STATE);
gtk_object_add_arg_type ("GstPlay::media_size",GTK_TYPE_ULONG,
GTK_ARG_READABLE, ARG_MEDIA_SIZE);
gtk_object_add_arg_type ("GstPlay::media_offset",GTK_TYPE_ULONG,
GTK_ARG_READABLE, ARG_MEDIA_OFFSET);
gtk_object_add_arg_type ("GstPlay::media_total_time",GTK_TYPE_ULONG,
GTK_ARG_READABLE, ARG_MEDIA_TOTAL_TIME);
gtk_object_add_arg_type ("GstPlay::media_current_time",GTK_TYPE_ULONG,
GTK_ARG_READABLE, ARG_MEDIA_CURRENT_TIME);
object_class->set_arg = gst_play_set_arg;
object_class->get_arg = gst_play_get_arg;
widget_class->realize = gst_play_realize;
}
static void
gst_play_init (GstPlay *play)
{
GstPlayPrivate *private = g_new0 (GstPlayPrivate, 1);
play->private = private;
/* create a new bin to hold the elements */
private->thread = gst_thread_new ("main_thread");
g_assert (private->thread != NULL);
private->pipeline = gst_pipeline_new ("main_pipeline");
g_assert (private->pipeline != NULL);
/* and an audio sink */
private->audio_play = gst_elementfactory_make ("audiosink","play_audio");
g_return_if_fail (private->audio_play != NULL);
gtk_signal_connect (GTK_OBJECT (private->audio_play), "handoff",
GTK_SIGNAL_FUNC (gst_play_audio_handoff), play);
/* and a video sink */
private->video_show = gst_elementfactory_make ("videosink","show");
g_return_if_fail (private->video_show != NULL);
gtk_object_set (GTK_OBJECT (private->video_show),"xv_enabled",FALSE,NULL);
gtk_signal_connect (GTK_OBJECT (private->video_show), "frame_displayed",
GTK_SIGNAL_FUNC (gst_play_frame_displayed), play);
gst_pipeline_add_sink (GST_PIPELINE (private->pipeline), private->audio_play);
gst_pipeline_add_sink (GST_PIPELINE (private->pipeline), private->video_show);
gst_bin_add (GST_BIN (private->thread), private->pipeline);
play->state = GST_PLAY_STOPPED;
private->src = NULL;
play->flags = 0;
private->muted = FALSE;
private->uri = NULL;
}
GstPlay *
gst_play_new ()
{
return GST_PLAY (gtk_type_new (GST_TYPE_PLAY));
}
static void
gst_play_eos (GstElement *element,
GstPlay *play)
{
gst_play_stop(play);
}
static void
gst_play_frame_displayed (GstElement *element,
GstPlay *play)
{
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_FRAME_DISPLAYED],
NULL);
}
static void
gst_play_audio_handoff (GstElement *element,
GstPlay *play)
{
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_AUDIO_PLAYED],
NULL);
}
GstPlayReturn
gst_play_set_uri (GstPlay *play,
const guchar *uri)
{
GstPlayPrivate *private;
g_return_val_if_fail (play != NULL, GST_PLAY_ERROR);
g_return_val_if_fail (GST_IS_PLAY (play), GST_PLAY_ERROR);
g_return_val_if_fail (uri != NULL, GST_PLAY_ERROR);
private = (GstPlayPrivate *)play->private;
if (private->src) {
}
if (private->uri) g_free (private->uri);
private->uri = g_strdup (uri);
private->src = gst_elementfactory_make ("disksrc", "disk_src");
g_return_val_if_fail (private->src != NULL, -1);
gtk_object_set (GTK_OBJECT (private->src),"location",uri,NULL);
gtk_signal_connect (GTK_OBJECT (private->src), "eos", GTK_SIGNAL_FUNC (gst_play_eos), play);
gst_pipeline_add_src (GST_PIPELINE (private->pipeline),GST_ELEMENT (private->src));
if (!gst_pipeline_autoplug (GST_PIPELINE (private->pipeline))) {
return GST_PLAY_UNKNOWN_MEDIA;
}
if (GST_PAD_CONNECTED (gst_element_get_pad (private->video_show, "sink"))) {
play->flags |= GST_PLAY_TYPE_VIDEO;
}
if (GST_PAD_CONNECTED (gst_element_get_pad (private->audio_play, "sink"))) {
play->flags |= GST_PLAY_TYPE_AUDIO;
}
return GST_PLAY_OK;
}
static void
gst_play_realize (GtkWidget *widget)
{
GstPlay *play;
GtkWidget *video_widget;
GstPlayPrivate *private;
g_return_if_fail (GST_IS_PLAY (widget));
play = GST_PLAY (widget);
private = (GstPlayPrivate *)play->private;
video_widget = gst_util_get_widget_arg (GTK_OBJECT (private->video_show),"widget");
if (video_widget) {
gtk_container_add (GTK_CONTAINER (widget), video_widget);
gtk_widget_show (video_widget);
}
if (GTK_WIDGET_CLASS (parent_class)->realize) {
GTK_WIDGET_CLASS (parent_class)->realize (widget);
}
}
void
gst_play_play (GstPlay *play)
{
GstPlayPrivate *private;
g_return_if_fail (play != NULL);
g_return_if_fail (GST_IS_PLAY (play));
private = (GstPlayPrivate *)play->private;
if (play->state == GST_PLAY_PLAYING) return;
if (play->state == GST_PLAY_STOPPED)
gst_element_set_state (GST_ELEMENT (private->thread),GST_STATE_READY);
gst_element_set_state (GST_ELEMENT (private->thread),GST_STATE_PLAYING);
play->state = GST_PLAY_PLAYING;
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_STATE_CHANGED],
play->state);
}
void
gst_play_pause (GstPlay *play)
{
GstPlayPrivate *private;
g_return_if_fail (play != NULL);
g_return_if_fail (GST_IS_PLAY (play));
private = (GstPlayPrivate *)play->private;
if (play->state == GST_PLAY_PAUSED) return;
gst_element_set_state (GST_ELEMENT (private->thread),GST_STATE_PAUSED);
play->state = GST_PLAY_PAUSED;
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_STATE_CHANGED],
play->state);
}
void
gst_play_stop (GstPlay *play)
{
GstPlayPrivate *private;
g_return_if_fail (play != NULL);
g_return_if_fail (GST_IS_PLAY (play));
if (play->state == GST_PLAY_STOPPED) return;
private = (GstPlayPrivate *)play->private;
gst_element_set_state (GST_ELEMENT (private->thread),GST_STATE_NULL);
gtk_object_set (GTK_OBJECT (private->src),"offset",0,NULL);
play->state = GST_PLAY_STOPPED;
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_STATE_CHANGED],
play->state);
}
static void
gst_play_set_arg (GtkObject *object,
GtkArg *arg,
guint id)
{
GstPlay *play;
play = GST_PLAY (object);
switch (id) {
case ARG_MUTE:
break;
default:
g_warning ("GstPlay: unknown arg!");
break;
}
}
static void
gst_play_get_arg (GtkObject *object,
GtkArg *arg,
guint id)
{
GstPlay *play;
GstPlayPrivate *private;
play = GST_PLAY (object);
private = (GstPlayPrivate *)play->private;
switch (id) {
case ARG_URI:
GTK_VALUE_STRING (*arg) = private->uri;
break;
case ARG_MUTE:
GTK_VALUE_BOOL (*arg) = private->muted;
break;
case ARG_STATE:
GTK_VALUE_INT (*arg) = play->state;
break;
case ARG_MEDIA_SIZE:
GTK_VALUE_LONG (*arg) = gst_util_get_long_arg (GTK_OBJECT (private->src), "size");
break;
case ARG_MEDIA_OFFSET:
GTK_VALUE_LONG (*arg) = gst_util_get_long_arg (GTK_OBJECT (private->src), "offset");
break;
case ARG_MEDIA_TOTAL_TIME:
break;
case ARG_MEDIA_CURRENT_TIME:
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
play_button = glade_xml_get_widget(xml, "toggle_play");
pause_button = glade_xml_get_widget(xml, "toggle_pause");
stop_button = glade_xml_get_widget(xml, "toggle_stop");
gstplay = glade_xml_get_widget(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);
g_snprintf(statusline, 200, "seeking");
/* create a new bin to hold the elements */
pipeline = gst_pipeline_new("pipeline");
g_assert(pipeline != NULL);
/* and an audio sink */
audio_play = gst_elementfactory_make("audiosink","play_audio");
g_return_val_if_fail(audio_play != NULL, -1);
/* and a video sink */
show = gst_elementfactory_make("videosink","show");
g_return_val_if_fail(show != NULL, -1);
gtk_object_set(GTK_OBJECT(show),"xv_enabled",FALSE,NULL);
gtk_signal_connect(GTK_OBJECT(show),"frame_displayed",
GTK_SIGNAL_FUNC(frame_displayed),NULL);
video = gst_util_get_widget_arg(GTK_OBJECT(show),"widget");
gnome_dock_set_client_area(GNOME_DOCK(glade_xml_get_widget(xml, "dock1")),
video);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audio_play);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), show);
/* connect the signals in the interface */
glade_xml_signal_autoconnect(xml);
if (argc > 1) {
gint ret;
ret = start_from_file(argv[1]);
if (ret < 0) exit(ret);
}
gst_main();
return 0;
}

View file

@ -6,20 +6,84 @@
#ifndef __GSTPLAY_H__
#define __GSTPLAY_H__
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include <gst/gst.h>
typedef struct _GstPlay GstPlay;
typedef struct _GstPlayClass GstPlayClass;
#define GST_TYPE_PLAY \
(gst_play_get_type())
#define GST_PLAY(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_PLAY,GstPlay))
#define GST_PLAY_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_PLAY,GstPlayClass))
#define GST_IS_PLAY(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_PLAY))
#define GST_IS_PLAY_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAY))
typedef enum {
GSTPLAY_PLAYING,
GSTPLAY_STOPPED,
GSTPLAY_PAUSE,
GST_PLAY_STOPPED,
GST_PLAY_PLAYING,
GST_PLAY_PAUSED,
} GstPlayState;
void change_state(GstPlayState new_state);
void show_next_picture();
typedef enum {
GST_PLAY_OK,
GST_PLAY_UNKNOWN_MEDIA,
GST_PLAY_ERROR,
} GstPlayReturn;
typedef enum {
GST_PLAY_TYPE_AUDIO = (1 << 0),
GST_PLAY_TYPE_VIDEO = (1 << 1),
} GstPlayMediaTypeFlags;
struct _GstPlay {
GtkHBox parent;
GstPlayState state;
GstPlayMediaTypeFlags flags;
gpointer private;
};
#define GST_PLAY_STATE(play) ((play)->state)
#define GST_PLAY_MEDIA_TYPE(play) ((play)->flags)
#define GST_PLAY_IS_AUDIO_TYPE(play) ((play)->flags & GST_PLAY_TYPE_AUDIO)
#define GST_PLAY_IS_VIDEO_TYPE(play) ((play)->flags & GST_PLAY_TYPE_VIDEO)
struct _GstPlayClass {
GtkHBoxClass parent_class;
void (*state_changed) (GstPlay *play, GstPlayState state);
void (*frame_displayed) (GstPlay *play);
void (*audio_played) (GstPlay *play);
};
GtkType gst_play_get_type (void);
/* setup the player */
GstPlay* gst_play_new (void);
GstPlayReturn gst_play_set_uri (GstPlay *play, const guchar *uri);
/* control the player */
void gst_play_play (GstPlay *play);
void gst_play_pause (GstPlay *play);
void gst_play_stop (GstPlay *play);
void gst_play_mute (GstPlay *play, gboolean mute);
/* information about the media stream */
gulong gst_play_get_media_size (GstPlay *play);
gulong gst_play_get_media_offset (GstPlay *play);
void gst_play_media_seek (GstPlay *play, gulong offset);
gulong gst_play_get_media_total_time (GstPlay *play);
gulong gst_play_get_media_current_time (GstPlay *play);
/* the autoplugged pipeline */
GstElement* gst_play_get_pipeline (GstPlay *play);
#endif /* __GSTPLAY_H__ */

24
gstplay/gstplayprivate.h Normal file
View file

@ -0,0 +1,24 @@
/*
* Initial main.c file generated by Glade. Edit as required.
* Glade will not overwrite this file.
*/
#ifndef __GSTPLAY_PRIVATE_H__
#define __GSTPLAY_PRIVATE_H__
#include <gst/gst.h>
typedef struct _GstPlayPrivate GstPlayPrivate;
struct _GstPlayPrivate {
GstElement *thread;
GstElement *pipeline;
GstElement *audio_play;
GstElement *video_show;
GstElement *src;
guchar *uri;
gboolean muted;
};
#endif /* __GSTPLAY_PRIVATE_H__ */

240
gstplay/gststatusarea.c Normal file
View file

@ -0,0 +1,240 @@
/*
* Initial main.c file generated by Glade. Edit as required.
* Glade will not overwrite this file.
*/
#include <config.h>
#include "gststatusarea.h"
static void gst_status_area_class_init(GstStatusAreaClass *klass);
static void gst_status_area_init(GstStatusArea *status_area);
static void gst_status_area_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_status_area_get_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_status_area_realize(GtkWidget *status_area);
static gint gst_status_area_expose(GtkWidget *widget, GdkEventExpose *event);
#define DEFAULT_HEIGHT 20
/* signals and args */
enum {
LAST_SIGNAL
};
enum {
ARG_0,
};
static GtkDrawingArea *parent_class = NULL;
static guint gst_status_area_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_status_area_get_type (void)
{
static GtkType status_area_type = 0;
if (!status_area_type) {
static const GtkTypeInfo status_area_info = {
"GstStatusArea",
sizeof(GstStatusArea),
sizeof(GstStatusAreaClass),
(GtkClassInitFunc)gst_status_area_class_init,
(GtkObjectInitFunc)gst_status_area_init,
NULL,
NULL,
(GtkClassInitFunc)NULL,
};
status_area_type = gtk_type_unique (gtk_widget_get_type (),&status_area_info);
}
return status_area_type;
}
static void
gst_status_area_class_init (GstStatusAreaClass *klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
parent_class = gtk_type_class (gtk_widget_get_type ());
object_class = (GtkObjectClass*)klass;
widget_class = (GtkWidgetClass*)klass;
object_class->set_arg = gst_status_area_set_arg;
object_class->get_arg = gst_status_area_get_arg;
widget_class->realize = gst_status_area_realize;
widget_class->expose_event = gst_status_area_expose;
}
static void
gst_status_area_init (GstStatusArea *status_area)
{
GTK_WIDGET(status_area)->requisition.height = DEFAULT_HEIGHT;
status_area->state = GST_STATUS_AREA_STATE_INIT;
}
GstStatusArea *
gst_status_area_new (void)
{
return GST_STATUS_AREA (gtk_type_new (GST_TYPE_STATUS_AREA));
}
static void
gst_status_area_realize (GtkWidget *widget)
{
GdkWindowAttr attributes;
gint attributes_mask;
GstStatusArea *status_area;
g_return_if_fail (widget != NULL);
g_return_if_fail(GST_IS_STATUS_AREA(widget));
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
status_area = GST_STATUS_AREA(widget);
attributes.x = widget->allocation.x;
attributes.y = widget->allocation.y;
attributes.width = widget->allocation.width;
attributes.height = widget->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.event_mask = gtk_widget_get_events (widget)
| GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
| GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
attributes.visual = gtk_widget_get_visual (widget);
attributes.colormap = gtk_widget_get_colormap (widget);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
widget->style = gtk_style_attach (widget->style, widget->window);
}
static gint
gst_status_area_expose(GtkWidget *widget,
GdkEventExpose *event)
{
GstStatusArea *status_area;
guchar *statustext;
g_return_val_if_fail (GST_IS_STATUS_AREA (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
status_area = GST_STATUS_AREA (widget);
if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget)) {
gdk_draw_rectangle (widget->window,
widget->style->black_gc,
TRUE,
0, 0,
widget->allocation.width,
widget->allocation.height);
switch (status_area->state) {
case GST_STATUS_AREA_STATE_INIT:
statustext = "Initializing";
break;
case GST_STATUS_AREA_STATE_PLAYING:
statustext = "Playing";
break;
case GST_STATUS_AREA_STATE_PAUSED:
statustext = "Paused";
break;
case GST_STATUS_AREA_STATE_STOPPED:
statustext = "Stopped";
break;
default:
statustext = "";
break;
}
gdk_draw_string (widget->window,
widget->style->font,
widget->style->white_gc,
8, 15, statustext);
if (status_area->playtime) {
gdk_draw_string (widget->window,
widget->style->font,
widget->style->white_gc,
widget->allocation.width-100, 15, status_area->playtime);
}
}
return FALSE;
}
void
gst_status_area_set_state (GstStatusArea *area,
GstStatusAreaState state)
{
g_return_if_fail(area != NULL);
g_return_if_fail(GST_IS_STATUS_AREA(area));
area->state = state;
if (GTK_WIDGET_VISIBLE(area))
gtk_widget_queue_draw(GTK_WIDGET(area));
}
void
gst_status_area_set_playtime (GstStatusArea *area,
const guchar *time)
{
g_return_if_fail(area != NULL);
g_return_if_fail(GST_IS_STATUS_AREA(area));
g_return_if_fail(time != NULL);
if (area->playtime) g_free (area->playtime);
area->playtime = g_strdup (time);
}
void
gst_status_area_set_streamtype (GstStatusArea *area,
const guchar *type)
{
}
void
gst_status_area_show_extended (GstStatusArea *area,
gboolean show)
{
}
static void
gst_status_area_set_arg(GtkObject *object,
GtkArg *arg,
guint id)
{
GstStatusArea *status_area;
status_area = GST_STATUS_AREA(object);
switch (id) {
default:
g_warning("GstStatusArea: unknown arg!");
break;
}
}
static void
gst_status_area_get_arg(GtkObject *object,
GtkArg *arg,
guint id)
{
GstStatusArea *status_area;
status_area = GST_STATUS_AREA(object);
switch (id) {
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}

51
gstplay/gststatusarea.h Normal file
View file

@ -0,0 +1,51 @@
#ifndef __GST_STATUS_AREA_H__
#define __GST_STATUS_AREA_H__
#include <gst/gst.h>
#include <gtk/gtk.h>
typedef struct _GstStatusArea GstStatusArea;
typedef struct _GstStatusAreaClass GstStatusAreaClass;
#define GST_TYPE_STATUS_AREA \
(gst_status_area_get_type())
#define GST_STATUS_AREA(obj) \
(GTK_CHECK_CAST((obj),GST_TYPE_STATUS_AREA,GstStatusArea))
#define GST_STATUS_AREA_CLASS(klass) \
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_STATUS_AREA,GstStatusAreaClass))
#define GST_IS_STATUS_AREA(obj) \
(GTK_CHECK_TYPE((obj),GST_TYPE_STATUS_AREA))
#define GST_IS_STATUS_AREA_CLASS(obj) \
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_STATUS_AREA))
typedef enum {
GST_STATUS_AREA_STATE_INIT,
GST_STATUS_AREA_STATE_PLAYING,
GST_STATUS_AREA_STATE_PAUSED,
GST_STATUS_AREA_STATE_STOPPED,
} GstStatusAreaState;
struct _GstStatusArea {
GtkWidget parent;
GstStatusAreaState state;
guchar *playtime;
};
struct _GstStatusAreaClass {
GtkWidgetClass parent_class;
};
GtkType gst_status_area_get_type (void);
GstStatusArea* gst_status_area_new (void);
void gst_status_area_set_state (GstStatusArea *area, GstStatusAreaState state);
void gst_status_area_set_playtime (GstStatusArea *area, const guchar *time);
void gst_status_area_set_streamtype (GstStatusArea *area, const guchar *type);
void gst_status_area_show_extended (GstStatusArea *area, gboolean show);
#endif /* __GST_STATUS_AREA_H__ */

View file

@ -22,7 +22,7 @@ extern GtkWidget *stop_button;
extern guchar statusline[];
extern guchar *statustext;
void update_buttons(int active)
void update_buttons(GstPlayState state)
{
gtk_signal_handler_block_by_func(GTK_OBJECT(play_button),
GTK_SIGNAL_FUNC (on_toggle_play_toggled),
@ -38,13 +38,13 @@ void update_buttons(int active)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_button), FALSE);
if (active == 0) {
if (state == GST_PLAY_PLAYING) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button), TRUE);
}
else if (active == 1) {
else if (state == GST_PLAY_PAUSED) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), TRUE);
}
else if (active == 2) {
else if (state == GST_PLAY_STOPPED) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stop_button), TRUE);
}
@ -70,17 +70,3 @@ void update_slider(GtkAdjustment *adjustment, gfloat value)
NULL);
}
void update_status_area(GtkWidget *widget)
{
gdk_draw_rectangle(widget->window,
widget->style->black_gc,
TRUE, 0,
0,
widget->allocation.width,
widget->allocation.height);
gdk_draw_string(widget->window,widget->style->font,widget->style->white_gc, 8, 15, statustext);
gdk_draw_string(widget->window,widget->style->font,widget->style->white_gc, widget->allocation.width-100, 15, statusline);
}

View file

@ -2,6 +2,8 @@
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#include "gstplay.h"
void update_status_area(GtkWidget *area);
void update_slider(GtkAdjustment *adjustment, gfloat value);
void update_buttons(int active);
void update_buttons(GstPlayState state);

34
gstplay/main.c Normal file
View file

@ -0,0 +1,34 @@
/*
* Initial main.c file generated by Glade. Edit as required.
* Glade will not overwrite this file.
*/
#include <config.h>
//#define DEBUG_ENABLED
#include <gnome.h>
#include <glade/glade.h>
#include "gstmediaplay.h"
int
main (int argc, char *argv[])
{
GstMediaPlay *play;
gst_init(&argc,&argv);
gnome_init ("gstreamer", VERSION, argc, argv);
play = gst_media_play_new();
if (argc > 1) {
gst_media_play_start_uri(play, argv[1]);
}
gst_main();
return 0;
}

View file

@ -57,8 +57,12 @@ static void gst_queue_init(GstQueue *queue);
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id);
static void gst_queue_get_arg(GtkObject *object,GtkArg *arg,guint id);
void gst_queue_push(GstConnection *connection);
void gst_queue_chain(GstPad *pad,GstBuffer *buf);
static void gst_queue_push(GstConnection *connection);
static void gst_queue_chain(GstPad *pad,GstBuffer *buf);
static void gst_queue_flush(GstQueue *queue);
static GstElementStateReturn gst_queue_change_state(GstElement *element);
static GstConnectionClass *parent_class = NULL;
//static guint gst_queue_signals[LAST_SIGNAL] = { 0 };
@ -85,9 +89,11 @@ gst_queue_get_type(void) {
static void gst_queue_class_init(GstQueueClass *klass) {
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
GstConnectionClass *gstconnection_class;
gtkobject_class = (GtkObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gstconnection_class = (GstConnectionClass*)klass;
parent_class = gtk_type_class(GST_TYPE_CONNECTION);
@ -101,6 +107,8 @@ static void gst_queue_class_init(GstQueueClass *klass) {
gtkobject_class->set_arg = gst_queue_set_arg;
gtkobject_class->get_arg = gst_queue_get_arg;
gstelement_class->change_state = gst_queue_change_state;
}
static void gst_queue_init(GstQueue *queue) {
@ -137,7 +145,14 @@ static void gst_queue_cleanup_buffers(gpointer data, gpointer user_data)
gst_buffer_unref(GST_BUFFER(data));
}
void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
static void gst_queue_flush(GstQueue *queue) {
g_slist_foreach(queue->queue, gst_queue_cleanup_buffers, gst_element_get_name(GST_ELEMENT(queue)));
g_slist_free(queue->queue);
queue->queue = NULL;
queue->level_buffers = 0;
}
static void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
GstQueue *queue;
gboolean tosignal = FALSE;
guchar *name;
@ -157,13 +172,9 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
DEBUG("queue: have queue lock\n");
if (GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLUSH)) {
g_slist_foreach(queue->queue, gst_queue_cleanup_buffers, name);
g_slist_free(queue->queue);
queue->queue = NULL;
queue->level_buffers = 0;
gst_queue_flush(queue);
}
DEBUG("queue: %s: chain %d %p\n", name, queue->level_buffers, buf);
while (queue->level_buffers >= queue->max_buffers) {
@ -199,7 +210,7 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) {
}
}
void gst_queue_push(GstConnection *connection) {
static void gst_queue_push(GstConnection *connection) {
GstQueue *queue = GST_QUEUE(connection);
GstBuffer *buf = NULL;
GSList *front;
@ -248,6 +259,26 @@ void gst_queue_push(GstConnection *connection) {
/* unlock now */
}
static GstElementStateReturn gst_queue_change_state(GstElement *element) {
GstQueue *queue;
g_return_val_if_fail(GST_IS_QUEUE(element),GST_STATE_FAILURE);
queue = GST_QUEUE(element);
DEBUG("gstqueue: state pending %d\n", GST_STATE_PENDING(element));
/* if going down into NULL state, clear out buffers*/
if (GST_STATE_PENDING(element) == GST_STATE_READY) {
/* otherwise (READY or higher) we need to open the file */
gst_queue_flush(queue);
}
/* if we haven't failed already, give the parent class a chance to ;-) */
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element);
return GST_STATE_SUCCESS;
}
static void gst_queue_set_arg(GtkObject *object,GtkArg *arg,guint id) {
GstQueue *queue;

View file

@ -75,11 +75,11 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
median = gst_elementfactory_make("median","median");
g_return_if_fail(median != NULL);
gtk_object_set(GTK_OBJECT(median),"filtersize",5,NULL);
gtk_object_set(GTK_OBJECT(median),"active",FALSE,NULL);
gtk_object_set(GTK_OBJECT(median),"active",TRUE,NULL);
gtk_object_set(GTK_OBJECT(smooth),"filtersize",16,NULL);
gtk_object_set(GTK_OBJECT(smooth),"tolerance",16,NULL);
gtk_object_set(GTK_OBJECT(smooth),"active",TRUE,NULL);
gtk_object_set(GTK_OBJECT(smooth),"active",FALSE,NULL);
encode = gst_elementfactory_make("mpeg2enc","encode");
g_return_if_fail(encode != NULL);

View file

@ -158,6 +158,7 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) {
gtk_object_set(GTK_OBJECT(smooth),"active",FALSE,NULL);
encode = gst_elementfactory_make("mpeg2enc","encode");
g_return_if_fail(encode != NULL);
//gtk_object_set(GTK_OBJECT(encode),"frames_per_second",25.0,NULL);
gtk_object_set(GTK_OBJECT(encode),"frames_per_second",29.97,NULL);
//encode = gst_elementfactory_make("mpeg1encoder","encode");
//gtk_object_set(GTK_OBJECT(show),"width",640, "height", 480,NULL);