From a3d5d3a62b3850506f0571d73809a46ea367bfb1 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 25 Jun 2000 21:38:00 +0000 Subject: [PATCH] Switched Cr and Cb in YUV2RGB fixed the avi parser (gstriff had wrong size) the system_encoder can now do video only ... Original commit message from CVS: Switched Cr and Cb in YUV2RGB fixed the avi parser (gstriff had wrong size) the system_encoder can now do video only system streams sanitized the colorspace and scaler api. added fast self modifying asm scaler. worked on the typefind stuff. added a cool media player (gstplay) it uses the typefinder to playback avi, mpeg1 (system and video) streams. It is also a testbed and a real app. --- configure.in | 1 + gst/elements/Makefile.am | 2 + gst/elements/gstaudiosink.h | 2 +- gst/elements/gstdisksrc.c | 4 + gst/elements/gstelements.c | 2 + gst/elements/gstqueue.c | 19 +- gst/gstpad.c | 24 ++- gst/gstpad.h | 1 + gst/gsttypefind.c | 79 -------- gst/gsttypefind.h | 68 ------- gst/types/gsttypes.c | 38 ---- gstplay/Makefile.am | 25 +++ gstplay/avi.c | 83 +++++++++ gstplay/callbacks.c | 84 +++++++++ gstplay/callbacks.h | 38 ++++ gstplay/codecs.h | 7 + gstplay/interface.c | 318 ++++++++++++++++++++++++++++++++ gstplay/interface.h | 5 + gstplay/main.c | 135 ++++++++++++++ gstplay/mpeg1.c | 124 +++++++++++++ gstplay/pixmaps/pause.xpm | 23 +++ gstplay/pixmaps/play.xpm | 23 +++ gstplay/pixmaps/stop.xpm | 23 +++ gstplay/support.c | 146 +++++++++++++++ gstplay/support.h | 34 ++++ libs/colorspace/yuv2rgb.c | 23 ++- libs/riff/gstriffparse.c | 2 +- libs/videoscale/Makefile.am | 2 +- libs/videoscale/gstvideoscale.c | 51 ++++- plugins/elements/Makefile.am | 2 + plugins/elements/gstaudiosink.h | 2 +- plugins/elements/gstdisksrc.c | 4 + plugins/elements/gstelements.c | 2 + plugins/elements/gstqueue.c | 19 +- test/avi2mpg.c | 74 +++++--- test/aviparse.c | 11 +- test/mp1parse.c | 2 +- test/vidcapture.c | 2 +- 38 files changed, 1254 insertions(+), 250 deletions(-) delete mode 100644 gst/gsttypefind.c delete mode 100644 gst/gsttypefind.h create mode 100644 gstplay/Makefile.am create mode 100644 gstplay/avi.c create mode 100644 gstplay/callbacks.c create mode 100644 gstplay/callbacks.h create mode 100644 gstplay/codecs.h create mode 100644 gstplay/interface.c create mode 100644 gstplay/interface.h create mode 100644 gstplay/main.c create mode 100644 gstplay/mpeg1.c create mode 100644 gstplay/pixmaps/pause.xpm create mode 100644 gstplay/pixmaps/play.xpm create mode 100644 gstplay/pixmaps/stop.xpm create mode 100644 gstplay/support.c create mode 100644 gstplay/support.h diff --git a/configure.in b/configure.in index 37d094bbc1..611dea7ad5 100644 --- a/configure.in +++ b/configure.in @@ -371,6 +371,7 @@ plugins/cobin/Makefile plugins/rtjpeg/Makefile plugins/capture/Makefile plugins/capture/v4l/Makefile +gstplay/Makefile test/Makefile test/xml/Makefile test/bindings/Makefile diff --git a/gst/elements/Makefile.am b/gst/elements/Makefile.am index f07e48cd60..420b551ef9 100644 --- a/gst/elements/Makefile.am +++ b/gst/elements/Makefile.am @@ -23,6 +23,7 @@ libgstelements_la_SOURCES = \ gstfdsink.c \ gstpipefilter.c \ gstqueue.c \ + gsttypefind.c \ gstsinesrc.c noinst_HEADERS = \ @@ -38,6 +39,7 @@ noinst_HEADERS = \ gstfdsink.h \ gstpipefilter.h \ gstqueue.h \ + gsttypefind.h \ gstsinesrc.h CFLAGS += -O2 -Wall diff --git a/gst/elements/gstaudiosink.h b/gst/elements/gstaudiosink.h index 9bdb53f6fe..f39d706616 100644 --- a/gst/elements/gstaudiosink.h +++ b/gst/elements/gstaudiosink.h @@ -44,7 +44,7 @@ GstElementDetails gst_audiosink_details; #define GST_IS_AUDIOSINK(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSINK)) #define GST_IS_AUDIOSINK_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK))) + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)) typedef struct _GstAudioSink GstAudioSink; typedef struct _GstAudioSinkClass GstAudioSinkClass; diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c index ac11143fe0..68bb6fafa9 100644 --- a/gst/elements/gstdisksrc.c +++ b/gst/elements/gstdisksrc.c @@ -150,6 +150,10 @@ static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { case ARG_BYTESPERREAD: src->bytes_per_read = GTK_VALUE_INT(*arg); break; + case ARG_OFFSET: + src->curoffset = GTK_VALUE_INT(*arg); + lseek(src->fd,src->curoffset, SEEK_SET); + break; default: break; } diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c index bf4ba0ee81..1d8fc439d5 100644 --- a/gst/elements/gstelements.c +++ b/gst/elements/gstelements.c @@ -35,6 +35,7 @@ #include #include #include +#include struct _elements_entry { @@ -59,6 +60,7 @@ struct _elements_entry _elements[] = { { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details }, { "queue", gst_queue_get_type, &gst_queue_details }, { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details }, + { "typefind", gst_typefind_get_type, &gst_typefind_details }, { NULL, 0 }, }; diff --git a/gst/elements/gstqueue.c b/gst/elements/gstqueue.c index a092f5d08e..6d95c9f0d4 100644 --- a/gst/elements/gstqueue.c +++ b/gst/elements/gstqueue.c @@ -147,20 +147,22 @@ static GstBuffer *gst_queue_pull(GstPad *pad) { void gst_queue_chain(GstPad *pad,GstBuffer *buf) { GstQueue *queue; gboolean tosignal = FALSE; + guchar *name; g_return_if_fail(pad != NULL); g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(buf != NULL); queue = GST_QUEUE(pad->parent); + name = gst_element_get_name(GST_ELEMENT(queue)); /* we have to lock the queue since we span threads */ GST_LOCK(queue); - DEBUG("queue: chain %d %p\n", queue->level_buffers, buf); + DEBUG("queue: %s: chain %d %p\n", name, queue->level_buffers, buf); if (queue->level_buffers >= queue->max_buffers) { - DEBUG("queue: waiting %d\n", queue->level_buffers); + DEBUG("queue: %s waiting %d\n", name, queue->level_buffers); GST_UNLOCK(queue); while (queue->level_buffers >= queue->max_buffers) { g_mutex_lock(queue->fulllock); @@ -169,7 +171,7 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) { g_mutex_unlock(queue->fulllock); } GST_LOCK(queue); - DEBUG("queue: waiting done %d\n", queue->level_buffers); + DEBUG("queue: %s waiting done %d\n", name, queue->level_buffers); } @@ -191,7 +193,7 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) { queue->level_buffers++; /* we can unlock now */ - DEBUG("queue: chain %d end\n", queue->level_buffers); + DEBUG("queue: %s chain %d end\n", name, queue->level_buffers); GST_UNLOCK(queue); if (tosignal) { @@ -207,10 +209,13 @@ void gst_queue_push(GstConnection *connection) { GstBuffer *buf = NULL; GList *front; gboolean tosignal = FALSE; + guchar *name; + + name = gst_element_get_name(GST_ELEMENT(queue)); /* have to lock for thread-safety */ GST_LOCK(queue); - DEBUG("queue: push %d\n", queue->level_buffers); + DEBUG("queue: %s push %d\n", name, queue->level_buffers); if (!queue->level_buffers) { GST_UNLOCK(queue); @@ -238,9 +243,9 @@ void gst_queue_push(GstConnection *connection) { g_mutex_unlock(queue->fulllock); } - DEBUG("queue: pushing %d %p\n", queue->level_buffers, buf); + DEBUG("queue: %s pushing %d %p\n", name, queue->level_buffers, buf); gst_pad_push(queue->srcpad,buf); - DEBUG("queue: pushing %d done\n", queue->level_buffers); + DEBUG("queue: %s pushing %d done\n", name, queue->level_buffers); /* unlock now */ } diff --git a/gst/gstpad.c b/gst/gstpad.c index c7b037a308..27daada54f 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -230,6 +230,28 @@ void gst_pad_chain(GstPad *pad) { (pad->chain)(pad,pad->bufpen); } +void gst_pad_disconnect(GstPad *srcpad,GstPad *sinkpad) { + + /* generic checks */ + g_return_if_fail(srcpad != NULL); + g_return_if_fail(GST_IS_PAD(srcpad)); + g_return_if_fail(srcpad->peer != NULL); + g_return_if_fail(sinkpad != NULL); + g_return_if_fail(GST_IS_PAD(sinkpad)); + g_return_if_fail(sinkpad->peer != NULL); + + g_return_if_fail((srcpad->direction == GST_PAD_SRC) && + (sinkpad->direction == GST_PAD_SINK)); + + /* first clear peers */ + srcpad->peer = NULL; + sinkpad->peer = NULL; + + srcpad->chain = NULL; + srcpad->pull = NULL; + +} + void gst_pad_connect(GstPad *srcpad,GstPad *sinkpad) { GstPad *temppad; @@ -273,7 +295,7 @@ void gst_pad_set_parent(GstPad *pad,GstObject *parent) { g_return_if_fail(GTK_IS_OBJECT(parent)); g_return_if_fail((gpointer)pad != (gpointer)parent); - //g_print("set parent %s\n", gst_element_get_name(parent)); + //g_print("set parent %s\n", gst_element_get_name(parent)); pad->parent = parent; } diff --git a/gst/gstpad.h b/gst/gstpad.h index 32da9afc8a..d48b34a1e9 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -110,6 +110,7 @@ GList *gst_pad_get_ghost_parents(GstPad *pad); GstPad *gst_pad_get_peer(GstPad *pad); void gst_pad_connect(GstPad *srcpad,GstPad *sinkpad); +void gst_pad_disconnect(GstPad *srcpad,GstPad *sinkpad); void gst_pad_push(GstPad *pad,GstBuffer *buffer); GstBuffer *gst_pad_pull(GstPad *pad); diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c deleted file mode 100644 index 473fa68340..0000000000 --- a/gst/gsttypefind.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Gnome-Streamer - * Copyright (C) <1999> Erik Walthinsen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#include - - -/* TypeFind signals and args */ -enum { - /* FILL ME */ - LAST_SIGNAL -}; - -enum { - ARG_0, - /* FILL ME */ -}; - - -static void gst_typefind_class_init(GstTypeFindClass *klass); -static void gst_typefind_init(GstTypeFind *typefind); - - -static GstElementClass *parent_class = NULL; -static guint gst_typefind_signals[LAST_SIGNAL] = { 0 }; - -GtkType -gst_typefind_get_type(void) { - static GtkType typefind_type = 0; - - if (!typefind_type) { - static const GtkTypeInfo typefind_info = { - "GstTypeFind", - sizeof(GstTypeFind), - sizeof(GstTypeFindClass), - (GtkClassInitFunc)gst_typefind_class_init, - (GtkObjectInitFunc)gst_typefind_init, - (GtkArgSetFunc)NULL, - (GtkArgGetFunc)NULL, - (GtkClassInitFunc)NULL, - }; - typefind_type = gtk_type_unique(GST_TYPE_ELEMENT,&typefind_info); - } - return typefind_type; -} - -static void -gst_typefind_class_init(GstTypeFindClass *klass) { - GtkObjectClass *gtkobject_class; - - gtkobject_class = (GtkObjectClass*)klass; - - parent_class = gtk_type_class(GST_TYPE_ELEMENT); -} - -static void gst_typefind_init(GstTypeFind *typefind) { -} - -GstObject *gst_typefind_new(gchar *name) { - GstObject *typefind = GST_OBJECT(gtk_type_new(GST_TYPE_TYPEFIND)); - gst_element_set_name(GST_ELEMENT(typefind),name); - return typefind; -} diff --git a/gst/gsttypefind.h b/gst/gsttypefind.h deleted file mode 100644 index 34bd714b7f..0000000000 --- a/gst/gsttypefind.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Gnome-Streamer - * Copyright (C) <1999> Erik Walthinsen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef __GST_TYPEFIND_H__ -#define __GST_TYPEFIND_H__ - - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define GST_TYPE_TYPEFIND \ - (gst_typefind_get_type()) -#define GST_TYPEFIND(obj) \ - (GTK_CHECK_CAST((obj),GST_TYPE_TYPEFIND,GstTypeFind)) -#define GST_TYPEFIND_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_TYPEFIND,GstTypeFindClass)) -#define GST_IS_TYPEFIND(obj) \ - (GTK_CHECK_TYPE((obj),GST_TYPE_TYPEFIND)) -#define GST_IS_TYPEFIND_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_TYPEFIND))) - -typedef struct _GstTypeFind GstTypeFind; -typedef struct _GstTypeFindClass GstTypeFindClass; - -struct _GstTypeFind { - GstElement element; - - GstPad *sinkpad; -}; - -struct _GstTypeFindClass { - GstElementClass parent_class; -}; - -GtkType gst_typefind_get_type(void); -GstObject *gst_typefind_new(gchar *name); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __GST_TYPEFIND_H__ */ diff --git a/gst/types/gsttypes.c b/gst/types/gsttypes.c index 990a17126a..ee377c7ad4 100644 --- a/gst/types/gsttypes.c +++ b/gst/types/gsttypes.c @@ -22,52 +22,14 @@ #include #include -gint mp3_typefind(GstBuffer *buf,gpointer *private); -gint wav_typefind(GstBuffer *buf,gpointer *private); - GstTypeFactory _factories[] = { { "audio/raw", ".raw", NULL }, - { "audio/mpeg audio/mp3", ".mp2 .mp3 .mpa .mpega", mp3_typefind }, - { "audio/wav", ".wav", wav_typefind }, { "audio/ac3", ".ac3", NULL }, - { "image/jpeg", ".jpg .jpeg", NULL }, { "video/raw image/raw", ".raw", NULL }, - { "video/mpeg video/mpeg1 video/mpeg-system", ".mpg", NULL }, - { "video/x-msvideo video/msvideo video/avi", ".avi", NULL }, { NULL, NULL, NULL }, }; -/* check to see if a buffer indicates the presence of an mp3 frame - * NOTE that this only checks for a potentially valid mp3 frame header - * and doesn't guarantee that it's a fully valid mp3 audio stream */ -gboolean mp3_typefind(GstBuffer *buf,gpointer *private) { - gulong head = GULONG_FROM_BE(*((gulong *)GST_BUFFER_DATA(buf))); - - if ((head & 0xffe00000) != 0xffe00000) - return FALSE; - if (!((head >> 17) & 3)) - return FALSE; - if (((head >> 12) & 0xf) == 0xf) - return FALSE; - if (!((head >> 12) & 0xf)) - return FALSE; - if (((head >> 10) & 0x3) == 0x3) - return FALSE; - - return TRUE; -} - -gboolean wav_typefind(GstBuffer *buf,gpointer *private) { - gulong *data = (gulong *)GST_BUFFER_DATA(buf); - - if (strncmp((char *)data[0], "RIFF", 4)) return FALSE; - if (strncmp((char *)data[2], "WAVE", 4)) return FALSE; - - return TRUE; -} - - GstPlugin *plugin_init(GModule *module) { GstPlugin *plugin; int i = 0; diff --git a/gstplay/Makefile.am b/gstplay/Makefile.am new file mode 100644 index 0000000000..0b9a7b6e58 --- /dev/null +++ b/gstplay/Makefile.am @@ -0,0 +1,25 @@ +## Process this file with automake to produce Makefile.in + +INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) \ + $(shell gnome-config --cflags gnomeui) + + +bin_PROGRAMS = gstplay + +gstplay_SOURCES = \ + main.c \ + mpeg1.c avi.c\ + support.c support.h \ + interface.c interface.h \ + callbacks.c callbacks.h + +noinst_HEADERS = codecs.h + +CFLAGS += -O2 -Wall + +gstplay_CFLAGS = $(shell gnome-config --cflags gnomeui) +gstplay_LDFLAGS = $(shell gnome-config --libs gnomeui) + +LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la + + diff --git a/gstplay/avi.c b/gstplay/avi.c new file mode 100644 index 0000000000..f173ca0f42 --- /dev/null +++ b/gstplay/avi.c @@ -0,0 +1,83 @@ + +#define BUFFER 1 +#define VIDEO_DECODER "mpeg_play" + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +extern GstElement *show; + +void avi_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) +{ + GstElement *play; + GstElement *audio_queue, *video_queue; + GstElement *audio_thread, *video_thread; + + g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); + + // connect to audio pad + //if (0) { + if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) { + // construct internal pipeline elements + play = gst_elementfactory_make("audiosink","play_audio"); + g_return_if_fail(play != NULL); + + // create the thread and pack stuff into it + audio_thread = gst_thread_new("audio_thread"); + g_return_if_fail(audio_thread != NULL); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play)); + + // set up pad connections + gst_element_add_ghost_pad(GST_ELEMENT(audio_thread), + gst_element_get_pad(play,"sink")); + + // construct queue and connect everything in the main pipelie + audio_queue = gst_elementfactory_make("queue","audio_queue"); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread)); + gst_pad_connect(pad, + gst_element_get_pad(audio_queue,"sink")); + gst_pad_connect(gst_element_get_pad(audio_queue,"src"), + gst_element_get_pad(audio_thread,"sink")); + + // set up thread state and kick things off + gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL); + g_print("setting to RUNNING state\n"); + gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING); + g_print("setting to PLAYING state\n"); + gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_PLAYING); + } else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { + //} else if (0) { + + // create the thread and pack stuff into it + video_thread = gst_thread_new("video_thread"); + g_return_if_fail(video_thread != NULL); + gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(show)); + + // set up pad connections + gst_element_add_ghost_pad(GST_ELEMENT(video_thread), + gst_element_get_pad(show,"sink")); + + // construct queue and connect everything in the main pipeline + video_queue = gst_elementfactory_make("queue","video_queue"); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_queue)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_thread)); + gst_pad_connect(pad, + gst_element_get_pad(video_queue,"sink")); + gst_pad_connect(gst_element_get_pad(video_queue,"src"), + gst_element_get_pad(video_thread,"sink")); + + // set up thread state and kick things off + gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL); + g_print("setting to RUNNING state\n"); + gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_RUNNING); + g_print("setting to PLAYING state\n"); + gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_PLAYING); + } + g_print("\n"); +} + diff --git a/gstplay/callbacks.c b/gstplay/callbacks.c new file mode 100644 index 0000000000..e8e5490594 --- /dev/null +++ b/gstplay/callbacks.c @@ -0,0 +1,84 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +extern GstElement *src; + +void +on_file1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +on_open1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +on_close1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +on_media1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +on_play2_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +on_pause1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +on_stop1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +on_about1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + +void +on_hscale1_value_changed (GtkAdjustment *adj, + gpointer user_data) +{ + gtk_object_set(GTK_OBJECT(src),"offset",10000000,NULL); + +} + diff --git a/gstplay/callbacks.h b/gstplay/callbacks.h new file mode 100644 index 0000000000..dfb61f6d05 --- /dev/null +++ b/gstplay/callbacks.h @@ -0,0 +1,38 @@ +#include + + +void +on_file1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_open1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_close1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_media1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_play2_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_pause1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_stop1_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_about1_activate (GtkMenuItem *menuitem, + gpointer user_data); +void +on_hscale1_value_changed (GtkAdjustment *adj, + gpointer user_data); + diff --git a/gstplay/codecs.h b/gstplay/codecs.h new file mode 100644 index 0000000000..a94c22406a --- /dev/null +++ b/gstplay/codecs.h @@ -0,0 +1,7 @@ + +/* mpeg1.c */ +void mpeg1_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline); +void mpeg1_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline); + +/* avi.c */ +void avi_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline); diff --git a/gstplay/interface.c b/gstplay/interface.c new file mode 100644 index 0000000000..26e8c40a8b --- /dev/null +++ b/gstplay/interface.c @@ -0,0 +1,318 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +static GnomeUIInfo file1_menu_uiinfo[] = +{ + { + GNOME_APP_UI_ITEM, N_("_Open..."), + NULL, + on_open1_activate, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_ITEM, N_("_Exit"), + NULL, + on_close1_activate, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_EXIT, + 0, 0, NULL + }, + GNOMEUIINFO_END +}; + +static GnomeUIInfo view2_menu_uiinfo[] = +{ + { + GNOME_APP_UI_ITEM, N_("_Media..."), + NULL, + on_media1_activate, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PROP, + 0, 0, NULL + }, + GNOMEUIINFO_END +}; + +static GnomeUIInfo play1_menu_uiinfo[] = +{ + { + GNOME_APP_UI_ITEM, N_("_Play"), + NULL, + on_play2_activate, NULL, NULL, + GNOME_APP_PIXMAP_FILENAME, "pixmaps/play.xpm", + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, N_("P_ause"), + NULL, + on_pause1_activate, NULL, NULL, + GNOME_APP_PIXMAP_FILENAME, "pixmaps/pause.xpm", + 0, 0, NULL + }, + { + GNOME_APP_UI_ITEM, N_("_Stop"), + NULL, + on_stop1_activate, NULL, NULL, + GNOME_APP_PIXMAP_FILENAME, "pixmaps/stop.xpm", + 0, 0, NULL + }, + GNOMEUIINFO_END +}; + +static GnomeUIInfo help1_menu_uiinfo[] = +{ + { + GNOME_APP_UI_ITEM, N_("_About"), + NULL, + on_about1_activate, NULL, NULL, + GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, + 0, 0, NULL + }, + GNOMEUIINFO_END +}; + +static GnomeUIInfo menubar1_uiinfo[] = +{ + { + GNOME_APP_UI_SUBTREE, N_("_File"), + NULL, + file1_menu_uiinfo, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_SUBTREE, N_("_View"), + NULL, + view2_menu_uiinfo, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_SUBTREE, N_("_Play"), + NULL, + play1_menu_uiinfo, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + { + GNOME_APP_UI_SUBTREE, N_("_Help"), + NULL, + help1_menu_uiinfo, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_END +}; + +GtkWidget* +create_window1 (GtkWidget *video_element) +{ + GtkWidget *window1; + GtkWidget *vbox1; + GtkWidget *handlebox2; + GtkWidget *menubar1; + GtkWidget *vbox2; + GtkWidget *hscale1; + GtkWidget *handlebox1; + GtkWidget *toolbar1; + GtkWidget *tmp_toolbar_icon; + GtkWidget *button6; + GtkWidget *button7; + GtkWidget *button8; + GtkWidget *vseparator1; + GtkObject *adjustment; + + window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_object_set_data (GTK_OBJECT (window1), "window1", window1); + gtk_window_set_title (GTK_WINDOW (window1), _("GStreamer Media Player")); + gtk_window_set_policy(GTK_WINDOW(window1), TRUE, TRUE, FALSE); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox1); + gtk_object_set_data_full (GTK_OBJECT (window1), "vbox1", vbox1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (window1), vbox1); + + handlebox2 = gtk_handle_box_new (); + gtk_widget_ref (handlebox2); + gtk_object_set_data_full (GTK_OBJECT (window1), "handlebox2", handlebox2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (handlebox2); + gtk_box_pack_start (GTK_BOX (vbox1), handlebox2, FALSE, FALSE, 0); + + menubar1 = gtk_menu_bar_new (); + gtk_widget_ref (menubar1); + gtk_object_set_data_full (GTK_OBJECT (window1), "menubar1", menubar1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (menubar1); + gtk_container_add (GTK_CONTAINER (handlebox2), menubar1); + gnome_app_fill_menu (GTK_MENU_SHELL (menubar1), menubar1_uiinfo, + NULL, FALSE, 0); + + gtk_widget_ref (menubar1_uiinfo[0].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "file1", + menubar1_uiinfo[0].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (file1_menu_uiinfo[0].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "open1", + file1_menu_uiinfo[0].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (file1_menu_uiinfo[1].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "separator1", + file1_menu_uiinfo[1].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (file1_menu_uiinfo[2].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "close1", + file1_menu_uiinfo[2].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (menubar1_uiinfo[1].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "view2", + menubar1_uiinfo[1].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (view2_menu_uiinfo[0].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "media1", + view2_menu_uiinfo[0].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (menubar1_uiinfo[2].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "play1", + menubar1_uiinfo[2].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (play1_menu_uiinfo[0].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "play2", + play1_menu_uiinfo[0].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (play1_menu_uiinfo[1].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "pause1", + play1_menu_uiinfo[1].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (play1_menu_uiinfo[2].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "stop1", + play1_menu_uiinfo[2].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (menubar1_uiinfo[3].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "help1", + menubar1_uiinfo[3].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_widget_ref (help1_menu_uiinfo[0].widget); + gtk_object_set_data_full (GTK_OBJECT (window1), "about1", + help1_menu_uiinfo[0].widget, + (GtkDestroyNotify) gtk_widget_unref); + + gtk_box_pack_start (GTK_BOX (vbox1), video_element, TRUE, TRUE, 0); + + vbox2 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox2); + gtk_object_set_data_full (GTK_OBJECT (window1), "vbox2", vbox2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox2); + gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0); + + adjustment = gtk_adjustment_new (0, 0, 100, 1, 10, 10); + hscale1 = gtk_hscale_new (GTK_ADJUSTMENT (adjustment)); + gtk_widget_ref (hscale1); + gtk_object_set_data_full (GTK_OBJECT (window1), "hscale1", hscale1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hscale1); + gtk_box_pack_start (GTK_BOX (vbox2), hscale1, TRUE, TRUE, 3); + gtk_scale_set_draw_value (GTK_SCALE (hscale1), FALSE); + gtk_scale_set_value_pos (GTK_SCALE (hscale1), GTK_POS_LEFT); + + gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed", + GTK_SIGNAL_FUNC (on_hscale1_value_changed), + NULL); + + handlebox1 = gtk_handle_box_new (); + gtk_widget_ref (handlebox1); + gtk_object_set_data_full (GTK_OBJECT (window1), "handlebox1", handlebox1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (handlebox1); + gtk_box_pack_start (GTK_BOX (vbox2), handlebox1, TRUE, TRUE, 1); + gtk_handle_box_set_shadow_type (GTK_HANDLE_BOX (handlebox1), GTK_SHADOW_NONE); + gtk_handle_box_set_snap_edge (GTK_HANDLE_BOX (handlebox1), GTK_POS_BOTTOM); + + toolbar1 = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS); + gtk_widget_ref (toolbar1); + gtk_object_set_data_full (GTK_OBJECT (window1), "toolbar1", toolbar1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (toolbar1); + gtk_container_add (GTK_CONTAINER (handlebox1), toolbar1); + gtk_container_set_border_width (GTK_CONTAINER (toolbar1), 3); + gtk_toolbar_set_space_size (GTK_TOOLBAR (toolbar1), 0); + gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar1), GTK_RELIEF_NONE); + + tmp_toolbar_icon = create_pixmap (window1, "pixmaps/play.xpm", TRUE); + button6 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar1), + GTK_TOOLBAR_CHILD_BUTTON, + NULL, + _("button6"), + NULL, NULL, + tmp_toolbar_icon, NULL, NULL); + gtk_widget_ref (button6); + gtk_object_set_data_full (GTK_OBJECT (window1), "button6", button6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button6); + + tmp_toolbar_icon = create_pixmap (window1, "pixmaps/pause.xpm", TRUE); + button7 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar1), + GTK_TOOLBAR_CHILD_BUTTON, + NULL, + _("button7"), + NULL, NULL, + tmp_toolbar_icon, NULL, NULL); + gtk_widget_ref (button7); + gtk_object_set_data_full (GTK_OBJECT (window1), "button7", button7, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button7); + + tmp_toolbar_icon = create_pixmap (window1, "pixmaps/stop.xpm", TRUE); + button8 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar1), + GTK_TOOLBAR_CHILD_BUTTON, + NULL, + _("button8"), + NULL, NULL, + tmp_toolbar_icon, NULL, NULL); + gtk_widget_ref (button8); + gtk_object_set_data_full (GTK_OBJECT (window1), "button8", button8, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button8); + + vseparator1 = gtk_vseparator_new (); + gtk_widget_ref (vseparator1); + gtk_object_set_data_full (GTK_OBJECT (window1), "vseparator1", vseparator1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vseparator1); + gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar1), vseparator1, NULL, NULL); + gtk_widget_set_usize (vseparator1, 8, 21); + + + return window1; +} + diff --git a/gstplay/interface.h b/gstplay/interface.h new file mode 100644 index 0000000000..26eee7d790 --- /dev/null +++ b/gstplay/interface.h @@ -0,0 +1,5 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_window1 (GtkWidget *video_element); diff --git a/gstplay/main.c b/gstplay/main.c new file mode 100644 index 0000000000..a21f433467 --- /dev/null +++ b/gstplay/main.c @@ -0,0 +1,135 @@ +/* + * Initial main.c file generated by Glade. Edit as required. + * Glade will not overwrite this file. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "interface.h" +#include "support.h" + +#include "codecs.h" + +extern gboolean _gst_plugin_spew; +gboolean idle_func(gpointer data); +GstElement *show; +GstElement *src; +GstPipeline *pipeline; + +void eof(GstSrc *src) { + g_print("have eos, quitting\n"); + exit(0); +} + +void have_type(GstSink *sink) { + gint type; + GstType *gsttype; + GstElement *parse = NULL; + + type = gst_util_get_int_arg(GTK_OBJECT(sink),"type"); + gsttype = gst_type_find_by_id(type); + + g_print("have type %d:%s\n", type, gsttype->mime); + + gst_bin_remove(GST_BIN(pipeline), GST_ELEMENT(sink)); + + gst_pad_disconnect(gst_element_get_pad(src,"src"), + gst_element_get_pad(GST_ELEMENT(sink),"sink")); + + if (strstr(gsttype->mime, "mpeg-system")) { + parse = gst_elementfactory_make("mpeg1parse","parse"); + gtk_signal_connect(GTK_OBJECT(parse),"new_pad", + GTK_SIGNAL_FUNC(mpeg1_new_pad_created),pipeline); + } + else if (strstr(gsttype->mime, "avi")) { + parse = gst_elementfactory_make("parseavi","parse"); + gtk_signal_connect(GTK_OBJECT(parse),"new_pad", + GTK_SIGNAL_FUNC(avi_new_pad_created),pipeline); + } + else if (strstr(gsttype->mime, "mpeg1")) { + mpeg1_setup_video_thread(gst_element_get_pad(src,"src"), show, pipeline); + } + else { + g_print("unknown media type\n"); + exit(0); + } + + if (parse) { + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(parse)); + gst_pad_connect(gst_element_get_pad(src,"src"), + gst_element_get_pad(parse,"sink")); + } + + gtk_object_set(GTK_OBJECT(src),"offset",0,NULL); +} + +int +main (int argc, char *argv[]) +{ + GtkWidget *window1; + GstElement *typefind; + + bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR); + textdomain (PACKAGE); + + gnome_init ("gstreamer", VERSION, argc, argv); + gst_init(&argc,&argv); + gst_plugin_load("mpeg1parse"); + gst_plugin_load("mp1videoparse"); + gst_plugin_load("mp3parse"); + gst_plugin_load("parsewav"); + gst_plugin_load("parseavi"); + gst_plugin_load("videosink"); + + show = gst_elementfactory_make("videosink","show"); + g_return_val_if_fail(show != NULL, -1); + + window1 = create_window1 (gst_util_get_widget_arg(GTK_OBJECT(show),"widget")); + gtk_widget_show (window1); + + pipeline = gst_pipeline_new("pipeline"); + g_return_val_if_fail(pipeline != NULL, -1); + + src = gst_elementfactory_make("disksrc","src"); + g_return_val_if_fail(src != NULL, -1); + gtk_object_set(GTK_OBJECT(src),"location",argv[1],NULL); + g_print("should be using file '%s'\n",argv[1]); + + typefind = gst_elementfactory_make("typefind","typefind"); + g_return_val_if_fail(typefind != NULL, -1); + + gtk_signal_connect(GTK_OBJECT(typefind),"have_type", + GTK_SIGNAL_FUNC(have_type),NULL); + + + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(typefind)); + + + gtk_signal_connect(GTK_OBJECT(src),"eos", + GTK_SIGNAL_FUNC(eof),NULL); + + gst_pad_connect(gst_element_get_pad(src,"src"), + gst_element_get_pad(typefind,"sink")); + + g_print("setting to RUNNING state\n"); + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_RUNNING); + + /* + * The following code was added by Glade to create one of each component + * (except popup menus), just so that you see something after building + * the project. Delete any components that you don't want shown initially. + */ + + while (1) { + gst_src_push(GST_SRC(src)); + } + + return 0; +} + diff --git a/gstplay/mpeg1.c b/gstplay/mpeg1.c new file mode 100644 index 0000000000..8eb99449e8 --- /dev/null +++ b/gstplay/mpeg1.c @@ -0,0 +1,124 @@ + +#define BUFFER 1 +#define VIDEO_DECODER "mpeg_play" + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "codecs.h" + + +extern gboolean _gst_plugin_spew; +extern GstElement *show; + +void mpeg1_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) +{ + GstElement *parse_audio, *decode, *play; + GstElement *audio_queue; + GstElement *audio_thread; + + g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); + + // connect to audio pad + //if (0) { + if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) { + gst_plugin_load("mp3parse"); + gst_plugin_load("mpg123"); + // construct internal pipeline elements + parse_audio = gst_elementfactory_make("mp3parse","parse_audio"); + g_return_if_fail(parse_audio != NULL); + decode = gst_elementfactory_make("mpg123","decode_audio"); + g_return_if_fail(decode != NULL); + play = gst_elementfactory_make("audiosink","play_audio"); + g_return_if_fail(play != NULL); + + // create the thread and pack stuff into it + audio_thread = gst_thread_new("audio_thread"); + g_return_if_fail(audio_thread != NULL); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio)); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode)); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play)); + + // set up pad connections + gst_element_add_ghost_pad(GST_ELEMENT(audio_thread), + gst_element_get_pad(parse_audio,"sink")); + gst_pad_connect(gst_element_get_pad(parse_audio,"src"), + gst_element_get_pad(decode,"sink")); + gst_pad_connect(gst_element_get_pad(decode,"src"), + gst_element_get_pad(play,"sink")); + + // construct queue and connect everything in the main pipelie + audio_queue = gst_elementfactory_make("queue","audio_queue"); + gtk_object_set(GTK_OBJECT(audio_queue),"max_level",BUFFER,NULL); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread)); + gst_pad_connect(pad, + gst_element_get_pad(audio_queue,"sink")); + gst_pad_connect(gst_element_get_pad(audio_queue,"src"), + gst_element_get_pad(audio_thread,"sink")); + + // set up thread state and kick things off + gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL); + g_print("setting to RUNNING state\n"); + gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING); + g_print("setting to PLAYING state\n"); + gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_PLAYING); + } else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { + //} else if (0) { + mpeg1_setup_video_thread(pad, show, pipeline); + } +} + +void mpeg1_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline) +{ + GstElement *parse_video, *decode_video; + GstElement *video_queue; + GstElement *video_thread; + + gst_plugin_load("mp1videoparse"); + gst_plugin_load(VIDEO_DECODER); + // construct internal pipeline elements + parse_video = gst_elementfactory_make("mp1videoparse","parse_video"); + g_return_if_fail(parse_video != NULL); + decode_video = gst_elementfactory_make(VIDEO_DECODER,"decode_video"); + g_return_if_fail(decode_video != NULL); + + // create the thread and pack stuff into it + video_thread = gst_thread_new("video_thread"); + g_return_if_fail(video_thread != NULL); + gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(parse_video)); + gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(decode_video)); + gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(show)); + + // set up pad connections + gst_element_add_ghost_pad(GST_ELEMENT(video_thread), + gst_element_get_pad(parse_video,"sink")); + gst_pad_connect(gst_element_get_pad(parse_video,"src"), + gst_element_get_pad(decode_video,"sink")); + gst_pad_connect(gst_element_get_pad(decode_video,"src"), + gst_element_get_pad(show,"sink")); + + // construct queue and connect everything in the main pipeline + video_queue = gst_elementfactory_make("queue","video_queue"); + gtk_object_set(GTK_OBJECT(video_queue),"max_level",BUFFER,NULL); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_queue)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_thread)); + gst_pad_connect(pad, + gst_element_get_pad(video_queue,"sink")); + gst_pad_connect(gst_element_get_pad(video_queue,"src"), + gst_element_get_pad(video_thread,"sink")); + + // set up thread state and kick things off + gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL); + g_print("setting to RUNNING state\n"); + gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_RUNNING); + g_print("setting to PLAYING state\n"); + gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_PLAYING); + + g_print("\n"); +} + diff --git a/gstplay/pixmaps/pause.xpm b/gstplay/pixmaps/pause.xpm new file mode 100644 index 0000000000..2283f242ab --- /dev/null +++ b/gstplay/pixmaps/pause.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * pause_xpm[] = { +"13 15 5 1", +" c None", +". c #949594", +"+ c #000000", +"@ c #8E8E8E", +"# c #FFFFFF", +"...... ......", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+++@# .+++@#", +".+@@@# .+@@@#", +".##### .#####"}; diff --git a/gstplay/pixmaps/play.xpm b/gstplay/pixmaps/play.xpm new file mode 100644 index 0000000000..5b7db49baf --- /dev/null +++ b/gstplay/pixmaps/play.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * play_back_xpm[] = { +"13 15 5 1", +" c None", +". c #949594", +"+ c #000000", +"@ c #8E8E8E", +"# c #FFFFFF", +"...... ", +".+++++. ", +".++++++. ", +".+++++++. ", +".++++++++. ", +".+++++++++. ", +".++++++++++. ", +".++++++++++@#", +".+++++++++@# ", +".++++++++@# ", +".+++++++@# ", +".++++++@# ", +".+++++@# ", +".+@@@@# ", +".##### "}; diff --git a/gstplay/pixmaps/stop.xpm b/gstplay/pixmaps/stop.xpm new file mode 100644 index 0000000000..2d159d0376 --- /dev/null +++ b/gstplay/pixmaps/stop.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * stop_back_xpm[] = { +"13 15 5 1", +" c None", +". c #949594", +"+ c #000000", +"@ c #8E8E8E", +"# c #FFFFFF", +".............", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".++++++++++@#", +".+@@@@@@@@@@#", +".############"}; diff --git a/gstplay/support.c b/gstplay/support.c new file mode 100644 index 0000000000..c76f33308d --- /dev/null +++ b/gstplay/support.c @@ -0,0 +1,146 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include + +#include "support.h" + +/* This is an internally used function to create pixmaps. */ +static GtkWidget* create_dummy_pixmap (GtkWidget *widget, + gboolean gnome_pixmap); + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +/* This is a dummy pixmap we use when a pixmap can't be found. */ +static char *dummy_pixmap_xpm[] = { +/* columns rows colors chars-per-pixel */ +"1 1 1 1", +" c None", +/* pixels */ +" ", +" " +}; + +/* This is an internally used function to create pixmaps. */ +static GtkWidget* +create_dummy_pixmap (GtkWidget *widget, + gboolean gnome_pixmap) +{ + GdkColormap *colormap; + GdkPixmap *gdkpixmap; + GdkBitmap *mask; + GtkWidget *pixmap; + + if (gnome_pixmap) + { + return gnome_pixmap_new_from_xpm_d (dummy_pixmap_xpm); + } + + colormap = gtk_widget_get_colormap (widget); + gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask, + NULL, dummy_pixmap_xpm); + if (gdkpixmap == NULL) + g_error ("Couldn't create replacement pixmap."); + pixmap = gtk_pixmap_new (gdkpixmap, mask); + gdk_pixmap_unref (gdkpixmap); + gdk_bitmap_unref (mask); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename, + gboolean gnome_pixmap) +{ + GtkWidget *pixmap; + GdkColormap *colormap; + GdkPixmap *gdkpixmap; + GdkBitmap *mask; + gchar *pathname; + + if (!filename || !filename[0]) + return create_dummy_pixmap (widget, gnome_pixmap); + + pathname = gnome_pixmap_file (filename); + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return create_dummy_pixmap (widget, gnome_pixmap); + } + + if (gnome_pixmap) + { + pixmap = gnome_pixmap_new_from_file (pathname); + g_free (pathname); + return pixmap; + } + + colormap = gtk_widget_get_colormap (widget); + gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask, + NULL, pathname); + if (gdkpixmap == NULL) + { + g_warning (_("Couldn't create pixmap from file: %s"), pathname); + g_free (pathname); + return create_dummy_pixmap (widget, gnome_pixmap); + } + g_free (pathname); + + pixmap = gtk_pixmap_new (gdkpixmap, mask); + gdk_pixmap_unref (gdkpixmap); + gdk_bitmap_unref (mask); + return pixmap; +} + +/* This is an internally used function to create imlib images. */ +GdkImlibImage* +create_image (const gchar *filename) +{ + GdkImlibImage *image; + gchar *pathname; + + pathname = gnome_pixmap_file (filename); + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + image = gdk_imlib_load_image (pathname); + g_free (pathname); + return image; +} + diff --git a/gstplay/support.h b/gstplay/support.h new file mode 100644 index 0000000000..d9bb0728a7 --- /dev/null +++ b/gstplay/support.h @@ -0,0 +1,34 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#include + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + +/* get_widget() is deprecated. Use lookup_widget instead. */ +#define get_widget lookup_widget + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename, + gboolean gnome_pixmap); + +GdkImlibImage* create_image (const gchar *filename); + diff --git a/libs/colorspace/yuv2rgb.c b/libs/colorspace/yuv2rgb.c index b65bbd46ff..98d9d5b02e 100644 --- a/libs/colorspace/yuv2rgb.c +++ b/libs/colorspace/yuv2rgb.c @@ -26,6 +26,8 @@ #include #include +//#undef HAVE_LIBMMX + #ifdef HAVE_LIBMMX #include "mmx.h" #endif @@ -85,8 +87,11 @@ GstColorSpaceConverter gst_colorspace_yuv2rgb_get_converter(GstColorSpace *space case GST_COLORSPACE_BGR32: space->color_tables = gst_colorspace_init_yuv(32, 0xFF0000, 0x00FF00, 0x0000FF); space->outsize = space->width*space->height*4; - //return gst_colorspace_yuv420P_to_bgr32; +#ifdef HAVE_LIBMMX return gst_colorspace_yuv420P_to_bgr32_mmx; +#else + return gst_colorspace_yuv420P_to_bgr32; +#endif case GST_COLORSPACE_RGB32: space->color_tables = gst_colorspace_init_yuv(32, 0x0000FF, 0x00FF00, 0xFF0000); space->outsize = space->width*space->height*4; @@ -107,8 +112,14 @@ GstColorSpaceConverter gst_colorspace_yuv2rgb_get_converter(GstColorSpace *space space->outsize = space->width*space->height*2; return gst_colorspace_yuv420P_to_rgb16; case GST_COLORSPACE_BGR565: + g_return_val_if_fail(space->visual != NULL, NULL); + space->color_tables = gst_colorspace_init_yuv(16, space->visual->red_mask, space->visual->green_mask, space->visual->blue_mask); space->outsize = space->width*space->height*2; +#ifdef HAVE_LIBMMX return gst_colorspace_yuv420P_to_bgr16_mmx; +#else + return gst_colorspace_yuv420P_to_rgb16; +#endif default: break; } @@ -447,7 +458,7 @@ gst_colorspace_init_yuv(long depth, long red_mask, long green_mask, long blue_ma */ static void -gst_colorspace_yuv_to_rgb16(tables, lum, cr, cb, out, rows, cols) +gst_colorspace_yuv_to_rgb16(tables, lum, cb, cr, out, rows, cols) GstColorSpaceYUVTables *tables; unsigned char *lum; unsigned char *cr; @@ -510,7 +521,7 @@ gst_colorspace_yuv_to_rgb16(tables, lum, cr, cb, out, rows, cols) } static void -gst_colorspace_yuv_to_rgb24(tables, lum, cr, cb, out, rows, cols) +gst_colorspace_yuv_to_rgb24(tables, lum, cb, cr, out, rows, cols) GstColorSpaceYUVTables *tables; unsigned char *lum; unsigned char *cr; @@ -595,7 +606,7 @@ gst_colorspace_yuv_to_rgb24(tables, lum, cr, cb, out, rows, cols) */ static void -gst_colorspace_yuv_to_rgb32(tables, lum, cr, cb, out, rows, cols) +gst_colorspace_yuv_to_rgb32(tables, lum, cb, cr, out, rows, cols) GstColorSpaceYUVTables *tables; unsigned char *lum; unsigned char *cr; @@ -692,9 +703,9 @@ gst_colorspace_yuv_to_bgr16_mmx(tables, lum, cr, cb, out, rows, cols) for (y=rows>>1; y; y--) { for (x=cols8; x; x--) { - movd_m2r(*(mmx_t *)cb, mm0); // 4 Cb 0 0 0 0 u3 u2 u1 u0 + movd_m2r(*(mmx_t *)cr, mm0); // 4 Cr 0 0 0 0 u3 u2 u1 u0 pxor_r2r(mm7, mm7); - movd_m2r(*(mmx_t *)cr, mm1); // 4 Cr 0 0 0 0 v3 v2 v1 v0 + movd_m2r(*(mmx_t *)cb, mm1); // 4 Cb 0 0 0 0 v3 v2 v1 v0 punpcklbw_r2r(mm7, mm0); // 4 W cb 0 u3 0 u2 0 u1 0 u0 punpcklbw_r2r(mm7, mm1); // 4 W cr 0 v3 0 v2 0 v1 0 v0 psubw_m2r(MMX_80w, mm0); diff --git a/libs/riff/gstriffparse.c b/libs/riff/gstriffparse.c index 1548b8da98..3385d15e12 100644 --- a/libs/riff/gstriffparse.c +++ b/libs/riff/gstriffparse.c @@ -67,7 +67,7 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) { buf = gst_buffer_new(); GST_BUFFER_DATA(buf) = riff->dataleft; - GST_BUFFER_SIZE(buf) = newsize; + size = GST_BUFFER_SIZE(buf) = newsize; off -= riff->dataleft_size; //last -= riff->dataleft_size; riff->dataleft = NULL; diff --git a/libs/videoscale/Makefile.am b/libs/videoscale/Makefile.am index 19b0920134..7285410a2a 100644 --- a/libs/videoscale/Makefile.am +++ b/libs/videoscale/Makefile.am @@ -9,7 +9,7 @@ libgstvideoscaleinclude_HEADERS = gstvideoscale.h noinst_HEADERS = yuv2rgb.h -CFLAGS += -Wall -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math +CFLAGS += -Wall -O1 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la diff --git a/libs/videoscale/gstvideoscale.c b/libs/videoscale/gstvideoscale.c index cca2eac8de..b047bdb4be 100644 --- a/libs/videoscale/gstvideoscale.c +++ b/libs/videoscale/gstvideoscale.c @@ -24,8 +24,10 @@ #include #include +#include static void gst_videoscale_scale_yuv(GstVideoScale *scale, unsigned char *src, unsigned char *dest); +static void gst_videoscale_scale_rgb(GstVideoScale *scale, unsigned char *src, unsigned char *dest); /* scalers */ static void generate_rowbytes(unsigned char *copy_row, int src_w, int dst_w, int bpp); @@ -39,6 +41,7 @@ static unsigned char gst_videoscale_bicubic(unsigned char *src, double x, double GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, GstVideoScaleMethod method) { GstVideoScale *new = g_malloc(sizeof(GstVideoScale)); + int scale_bytes; new->source_width = sw; new->source_height = sh; @@ -48,21 +51,35 @@ GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, Gs new->method = method; - new->scale = gst_videoscale_scale_yuv; + switch (format) { + case GST_COLORSPACE_YUV420P: + new->scale = gst_videoscale_scale_yuv; + scale_bytes = 1; + break; + case GST_COLORSPACE_RGB555: + case GST_COLORSPACE_RGB565: + case GST_COLORSPACE_BGR555: + case GST_COLORSPACE_BGR565: + new->scale = gst_videoscale_scale_rgb; + scale_bytes = 2; + break; + } switch (method) { case GST_VIDEOSCALE_NEAREST: - generate_rowbytes(new->copy_row, sw, dw, 1); + generate_rowbytes(new->copy_row, sw, dw, scale_bytes); new->scaler = gst_videoscale_scale_nearest; DEBUG("videoscale: scaling method NEAREST\n"); break; case GST_VIDEOSCALE_BILINEAR: new->scaler = gst_videoscale_scale_plane_slow; new->filter = gst_videoscale_bilinear; + DEBUG("videoscale: scaling method BILINEAR\n"); break; case GST_VIDEOSCALE_BICUBIC: new->scaler = gst_videoscale_scale_plane_slow; new->filter = gst_videoscale_bicubic; + DEBUG("videoscale: scaling method BICUBIC\n"); break; default: g_print("videoscale: unsupported scaling method %d\n", method); @@ -77,6 +94,20 @@ void gst_videoscale_destroy(GstVideoScale *scale) g_free(scale); } +static void gst_videoscale_scale_rgb(GstVideoScale *scale, unsigned char *src, unsigned char *dest) +{ + int sw = scale->source_width; + int sh = scale->source_height; + int dw = scale->dest_width; + int dh = scale->dest_height; + DEBUG("videoscale: scaling RGB %dx%d to %dx%d\n", sw, sh, dw, dh); + + dw = ((dw + 1) & ~1) << 1; + sw = sw<<1; + DEBUG("videoscale: %p %p\n", src, dest); + scale->scaler(scale, src, dest, sw, sh, dw, dh); +} + static void gst_videoscale_scale_yuv(GstVideoScale *scale, unsigned char *src, unsigned char *dest) { int sw = scale->source_width; @@ -114,6 +145,8 @@ static unsigned char gst_videoscale_bilinear(unsigned char *src, double x, doubl double dest; int color; + DEBUG("videoscale: scaling bilinear %dx%d\n", sw, sh); + dest=(1-a)*(1-b)*RC(j,k)+ a*(1-b)*RC(j+1,k); @@ -168,12 +201,17 @@ static void gst_videoscale_scale_plane_slow(GstVideoScale *scale, unsigned char double xr, yr; int x, y; + DEBUG("videoscale: scale plane slow %dx%d %dx%d %g %g %p %p\n", sw, sh, dw, dh, zoomx, zoomy, src, dest); + for (y=0; ytemp = scale->copy_row; - DEBUG("videoscale: scaling nearest %p\n", scale->copy_row); + DEBUG("videoscale: scaling nearest %p %p %p %d\n", scale->copy_row, src, dest, dw); + pos = 0x10000; inc = (sh<<16)/dh; - for (y = dh; y; y--) { + for (y = dh; y > 0; y--) { while (pos >0x10000) { src += sw; pos-=0x10000; } + __asm__ __volatile__ (" movl %2, %%eax\n call *%%eax @@ -260,7 +301,9 @@ static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *sr : "=&D" (u1), "=&S" (u2) : "g" (scale->temp), "0" (dest), "1" (src) : "memory" ); + + //g_print("videoscale: scaling nearest %d\n", y); dest+= dw; pos += inc; diff --git a/plugins/elements/Makefile.am b/plugins/elements/Makefile.am index f07e48cd60..420b551ef9 100644 --- a/plugins/elements/Makefile.am +++ b/plugins/elements/Makefile.am @@ -23,6 +23,7 @@ libgstelements_la_SOURCES = \ gstfdsink.c \ gstpipefilter.c \ gstqueue.c \ + gsttypefind.c \ gstsinesrc.c noinst_HEADERS = \ @@ -38,6 +39,7 @@ noinst_HEADERS = \ gstfdsink.h \ gstpipefilter.h \ gstqueue.h \ + gsttypefind.h \ gstsinesrc.h CFLAGS += -O2 -Wall diff --git a/plugins/elements/gstaudiosink.h b/plugins/elements/gstaudiosink.h index 9bdb53f6fe..f39d706616 100644 --- a/plugins/elements/gstaudiosink.h +++ b/plugins/elements/gstaudiosink.h @@ -44,7 +44,7 @@ GstElementDetails gst_audiosink_details; #define GST_IS_AUDIOSINK(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSINK)) #define GST_IS_AUDIOSINK_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK))) + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)) typedef struct _GstAudioSink GstAudioSink; typedef struct _GstAudioSinkClass GstAudioSinkClass; diff --git a/plugins/elements/gstdisksrc.c b/plugins/elements/gstdisksrc.c index ac11143fe0..68bb6fafa9 100644 --- a/plugins/elements/gstdisksrc.c +++ b/plugins/elements/gstdisksrc.c @@ -150,6 +150,10 @@ static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { case ARG_BYTESPERREAD: src->bytes_per_read = GTK_VALUE_INT(*arg); break; + case ARG_OFFSET: + src->curoffset = GTK_VALUE_INT(*arg); + lseek(src->fd,src->curoffset, SEEK_SET); + break; default: break; } diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c index bf4ba0ee81..1d8fc439d5 100644 --- a/plugins/elements/gstelements.c +++ b/plugins/elements/gstelements.c @@ -35,6 +35,7 @@ #include #include #include +#include struct _elements_entry { @@ -59,6 +60,7 @@ struct _elements_entry _elements[] = { { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details }, { "queue", gst_queue_get_type, &gst_queue_details }, { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details }, + { "typefind", gst_typefind_get_type, &gst_typefind_details }, { NULL, 0 }, }; diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index a092f5d08e..6d95c9f0d4 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -147,20 +147,22 @@ static GstBuffer *gst_queue_pull(GstPad *pad) { void gst_queue_chain(GstPad *pad,GstBuffer *buf) { GstQueue *queue; gboolean tosignal = FALSE; + guchar *name; g_return_if_fail(pad != NULL); g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(buf != NULL); queue = GST_QUEUE(pad->parent); + name = gst_element_get_name(GST_ELEMENT(queue)); /* we have to lock the queue since we span threads */ GST_LOCK(queue); - DEBUG("queue: chain %d %p\n", queue->level_buffers, buf); + DEBUG("queue: %s: chain %d %p\n", name, queue->level_buffers, buf); if (queue->level_buffers >= queue->max_buffers) { - DEBUG("queue: waiting %d\n", queue->level_buffers); + DEBUG("queue: %s waiting %d\n", name, queue->level_buffers); GST_UNLOCK(queue); while (queue->level_buffers >= queue->max_buffers) { g_mutex_lock(queue->fulllock); @@ -169,7 +171,7 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) { g_mutex_unlock(queue->fulllock); } GST_LOCK(queue); - DEBUG("queue: waiting done %d\n", queue->level_buffers); + DEBUG("queue: %s waiting done %d\n", name, queue->level_buffers); } @@ -191,7 +193,7 @@ void gst_queue_chain(GstPad *pad,GstBuffer *buf) { queue->level_buffers++; /* we can unlock now */ - DEBUG("queue: chain %d end\n", queue->level_buffers); + DEBUG("queue: %s chain %d end\n", name, queue->level_buffers); GST_UNLOCK(queue); if (tosignal) { @@ -207,10 +209,13 @@ void gst_queue_push(GstConnection *connection) { GstBuffer *buf = NULL; GList *front; gboolean tosignal = FALSE; + guchar *name; + + name = gst_element_get_name(GST_ELEMENT(queue)); /* have to lock for thread-safety */ GST_LOCK(queue); - DEBUG("queue: push %d\n", queue->level_buffers); + DEBUG("queue: %s push %d\n", name, queue->level_buffers); if (!queue->level_buffers) { GST_UNLOCK(queue); @@ -238,9 +243,9 @@ void gst_queue_push(GstConnection *connection) { g_mutex_unlock(queue->fulllock); } - DEBUG("queue: pushing %d %p\n", queue->level_buffers, buf); + DEBUG("queue: %s pushing %d %p\n", name, queue->level_buffers, buf); gst_pad_push(queue->srcpad,buf); - DEBUG("queue: pushing %d done\n", queue->level_buffers); + DEBUG("queue: %s pushing %d done\n", name, queue->level_buffers); /* unlock now */ } diff --git a/test/avi2mpg.c b/test/avi2mpg.c index 784f5c3767..be617acec3 100644 --- a/test/avi2mpg.c +++ b/test/avi2mpg.c @@ -4,11 +4,13 @@ #include #include +#define BUFFER 1 extern gboolean _gst_plugin_spew; gboolean idle_func(gpointer data); int fd; char *outfile; +GstElement *mux; void eof(GstSrc *src) { g_print("have eos, quitting\n"); @@ -16,11 +18,10 @@ void eof(GstSrc *src) { } void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { - GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *encode, *smooth; + GstElement *parse_audio, *parse_video, *decode, *decode_video, *audio_encode; + GstElement *encode, *smooth, *median; GstElement *audio_queue, *video_queue; GstElement *audio_thread, *video_thread; - GstElement *fdsink; - GstElementFactory *fdsinkfactory; GtkWidget *appwindow; @@ -29,21 +30,27 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { // connect to audio pad //if (0) { if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) { + gst_plugin_load("mpegaudio"); // construct internal pipeline elements - play = gst_elementfactory_make("audiosink","play_audio"); - g_return_if_fail(play != NULL); + audio_encode = gst_elementfactory_make("mpegaudio","audio_encode"); + g_return_if_fail(audio_encode != NULL); // create the thread and pack stuff into it audio_thread = gst_thread_new("audio_thread"); g_return_if_fail(audio_thread != NULL); - gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play)); + gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(audio_encode)); + + gtk_object_set(GTK_OBJECT(mux),"audio","00",NULL); // set up pad connections gst_element_add_ghost_pad(GST_ELEMENT(audio_thread), - gst_element_get_pad(play,"sink")); + gst_element_get_pad(audio_encode,"sink")); + gst_pad_connect(gst_element_get_pad(audio_encode,"src"), + gst_element_get_pad(mux,"audio_00")); // construct queue and connect everything in the main pipelie audio_queue = gst_elementfactory_make("queue","audio_queue"); + gtk_object_set(GTK_OBJECT(audio_queue),"max_level",BUFFER,NULL); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue)); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread)); gst_pad_connect(pad, @@ -51,6 +58,7 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { gst_pad_connect(gst_element_get_pad(audio_queue,"src"), gst_element_get_pad(audio_thread,"sink")); + // set up thread state and kick things off gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL); g_print("setting to RUNNING state\n"); @@ -65,38 +73,41 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { gst_plugin_load("mpeg2enc"); // construct internal pipeline elements smooth = gst_elementfactory_make("smooth","smooth"); - //smooth = gst_elementfactory_make("median","median"); g_return_if_fail(smooth != NULL); - gtk_object_set(GTK_OBJECT(smooth),"filtersize",2,NULL); - gtk_object_set(GTK_OBJECT(smooth),"tolerance",4,NULL); + 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(smooth),"filtersize",16,NULL); + gtk_object_set(GTK_OBJECT(smooth),"tolerance",16,NULL); + gtk_object_set(GTK_OBJECT(smooth),"active",TRUE,NULL); + encode = gst_elementfactory_make("mpeg2enc","encode"); g_return_if_fail(encode != NULL); - fd = open(outfile,O_CREAT|O_RDWR|O_TRUNC); - fdsinkfactory = gst_elementfactory_find("fdsink"); - g_return_if_fail(fdsinkfactory != NULL); - fdsink = gst_elementfactory_create(fdsinkfactory,"fdsink"); - g_return_if_fail(fdsink != NULL); - gtk_object_set(GTK_OBJECT(fdsink),"fd",fd,NULL); + gtk_object_set(GTK_OBJECT(mux),"video","00",NULL); // create the thread and pack stuff into it video_thread = gst_thread_new("video_thread"); g_return_if_fail(video_thread != NULL); gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(smooth)); + gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(median)); gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(encode)); - gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(fdsink)); + gst_pad_connect(gst_element_get_pad(median,"src"), + gst_element_get_pad(smooth,"sink")); gst_pad_connect(gst_element_get_pad(smooth,"src"), gst_element_get_pad(encode,"sink")); gst_pad_connect(gst_element_get_pad(encode,"src"), - gst_element_get_pad(fdsink,"sink")); + gst_element_get_pad(mux,"video_00")); // set up pad connections gst_element_add_ghost_pad(GST_ELEMENT(video_thread), - gst_element_get_pad(smooth,"sink")); - //gst_element_get_pad(encode,"sink")); + gst_element_get_pad(median,"sink")); // construct queue and connect everything in the main pipeline video_queue = gst_elementfactory_make("queue","video_queue"); + gtk_object_set(GTK_OBJECT(video_queue),"max_level",BUFFER,NULL); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_queue)); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_thread)); gst_pad_connect(pad, @@ -116,13 +127,15 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { int main(int argc,char *argv[]) { GstPipeline *pipeline; - GstElement *src, *parse; + GstElement *src, *parse, *fdsink; + GstElementFactory *fdsinkfactory; g_print("have %d args\n",argc); //_gst_plugin_spew = TRUE; gst_init(&argc,&argv); gst_plugin_load("parseavi"); + gst_plugin_load("system_encode"); pipeline = gst_pipeline_new("pipeline"); g_return_if_fail(pipeline != NULL); @@ -131,15 +144,24 @@ int main(int argc,char *argv[]) { g_return_if_fail(src != NULL); gtk_object_set(GTK_OBJECT(src),"location",argv[1],NULL); g_print("should be using file '%s'\n",argv[1]); - - g_print("should be using output file '%s'\n",argv[2]); - outfile = argv[2]; - parse = gst_elementfactory_make("parseavi","parse"); g_return_if_fail(parse != NULL); + mux = gst_elementfactory_make("system_encode","mux"); + g_return_if_fail(mux != NULL); + g_print("should be using output file '%s'\n",argv[2]); + outfile = argv[2]; + fd = open(argv[2],O_CREAT|O_RDWR|O_TRUNC); + fdsinkfactory = gst_elementfactory_find("fdsink"); + g_return_if_fail(fdsinkfactory != NULL); + fdsink = gst_elementfactory_create(fdsinkfactory,"fdsink"); + g_return_if_fail(fdsink != NULL); + gtk_object_set(GTK_OBJECT(fdsink),"fd",fd,NULL); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src)); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(parse)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(mux)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(fdsink)); gtk_signal_connect(GTK_OBJECT(parse),"new_pad", GTK_SIGNAL_FUNC(new_pad_created),pipeline); @@ -149,6 +171,8 @@ int main(int argc,char *argv[]) { gst_pad_connect(gst_element_get_pad(src,"src"), gst_element_get_pad(parse,"sink")); + gst_pad_connect(gst_element_get_pad(mux,"src"), + gst_element_get_pad(fdsink,"sink")); g_print("setting to RUNNING state\n"); gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_RUNNING); diff --git a/test/aviparse.c b/test/aviparse.c index 556254e4a7..2ed80f57ab 100644 --- a/test/aviparse.c +++ b/test/aviparse.c @@ -11,7 +11,7 @@ void eof(GstSrc *src) { } void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { - GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *show, *scale; + GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *show; GstElement *audio_queue, *video_queue; GstElement *audio_thread, *video_thread; @@ -53,12 +53,8 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { } else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { //} else if (0) { - gst_plugin_load("videoscale"); gst_plugin_load("videosink"); // construct internal pipeline elements - scale = gst_elementfactory_make("videoscale","videoscale"); - g_return_if_fail(scale != NULL); - gtk_object_set(GTK_OBJECT(scale),"width",704, "height", 570,NULL); show = gst_elementfactory_make("videosink","show"); g_return_if_fail(show != NULL); //gtk_object_set(GTK_OBJECT(show),"width",640, "height", 480,NULL); @@ -71,14 +67,11 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { // create the thread and pack stuff into it video_thread = gst_thread_new("video_thread"); g_return_if_fail(video_thread != NULL); - gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(scale)); gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(show)); // set up pad connections gst_element_add_ghost_pad(GST_ELEMENT(video_thread), - gst_element_get_pad(scale,"sink")); - gst_pad_connect(gst_element_get_pad(scale,"src"), - gst_element_get_pad(show,"sink")); + gst_element_get_pad(show,"sink")); // construct queue and connect everything in the main pipeline video_queue = gst_elementfactory_make("queue","video_queue"); diff --git a/test/mp1parse.c b/test/mp1parse.c index 5670b389e8..55c10876dc 100644 --- a/test/mp1parse.c +++ b/test/mp1parse.c @@ -1,5 +1,5 @@ -#define BUFFER 1 +#define BUFFER 20 #define VIDEO_DECODER "mpeg_play" #include diff --git a/test/vidcapture.c b/test/vidcapture.c index c0555bff03..fcf229cfa0 100644 --- a/test/vidcapture.c +++ b/test/vidcapture.c @@ -29,7 +29,7 @@ int main(int argc,char *argv[]) { compress = gst_elementfactory_create(compressfactory,"jpegenc"); encoderfactory = gst_elementfactory_find("aviencoder"); encoder = gst_elementfactory_create(encoderfactory,"aviencoder"); - gtk_object_set(GTK_OBJECT(videosrc),"width",384,"height",288,NULL); + gtk_object_set(GTK_OBJECT(videosrc),"width",320,"height",240,NULL); gtk_object_set(GTK_OBJECT(videosrc),"format",9,NULL); gtk_object_set(GTK_OBJECT(encoder),"video","00:I420",NULL);