Added a pull function in the gstpad. Modified the videosink to implement the pull. This function allows a source elem...

Original commit message from CVS:
Added a pull function in the gstpad. Modified the videosink to implement
the pull. This function allows a source element to request a buffer
from the destination. This is much more efficient because the
videosink can then pass a buffer with SHM to the element, which does
not require an aditional memcpy.
removed scaling from the videosink. I need something better.
This commit is contained in:
Wim Taymans 2000-02-26 18:55:14 +00:00
parent 54367bb65c
commit c144819530
4 changed files with 30 additions and 6 deletions

View file

@ -79,6 +79,7 @@ static void gst_pad_init(GstPad *pad) {
pad->direction = GST_PAD_UNKNOWN; pad->direction = GST_PAD_UNKNOWN;
pad->peer = NULL; pad->peer = NULL;
pad->chain = NULL; pad->chain = NULL;
pad->pull = NULL;
pad->parent = NULL; pad->parent = NULL;
pad->ghostparents = NULL; pad->ghostparents = NULL;
} }
@ -128,6 +129,15 @@ gchar *gst_pad_get_name(GstPad *pad) {
return pad->name; return pad->name;
} }
void gst_pad_set_pull_function(GstPad *pad,GstPadPullFunction pull) {
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
fprintf(stderr, "pad setting pull function\n");
pad->pull = pull;
}
void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain) { void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain) {
g_return_if_fail(pad != NULL); g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(GST_IS_PAD(pad));
@ -163,7 +173,11 @@ GstBuffer *gst_pad_pull(GstPad *pad) {
g_return_if_fail(pad != NULL); g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(GST_IS_PAD(pad));
if (pad->bufpen == NULL) { // if the pull function exists for the pad, call it directly
if (pad->pull) {
return (pad->pull)(pad->peer);
// else we're likely going to have to coroutine it
} else if (pad->bufpen == NULL) {
g_print("no buffer available, will have to do something about it\n"); g_print("no buffer available, will have to do something about it\n");
peerparent = GST_ELEMENT(pad->peer->parent); peerparent = GST_ELEMENT(pad->peer->parent);
// if they're a cothread too, we can just switch to them // if they're a cothread too, we can just switch to them
@ -221,6 +235,8 @@ void gst_pad_connect(GstPad *srcpad,GstPad *sinkpad) {
/* now copy the chain pointer from sink to src */ /* now copy the chain pointer from sink to src */
srcpad->chain = sinkpad->chain; srcpad->chain = sinkpad->chain;
/* and the pull function */
srcpad->pull = sinkpad->pull;
/* set the connected flag */ /* set the connected flag */
/* FIXME: set connected flag */ /* FIXME: set connected flag */

View file

@ -45,6 +45,7 @@ extern "C" {
// quick test to see if the pad is connected // quick test to see if the pad is connected
#define GST_PAD_CONNECTED(pad) ((pad)->peer != NULL) #define GST_PAD_CONNECTED(pad) ((pad)->peer != NULL)
#define GST_PAD_CAN_PULL(pad) ((pad)->pull != NULL)
typedef struct _GstPad GstPad; typedef struct _GstPad GstPad;
typedef struct _GstPadClass GstPadClass; typedef struct _GstPadClass GstPadClass;
@ -53,6 +54,7 @@ typedef struct _GstPadClass GstPadClass;
* pad is the sink pad (so the same chain function can be used for N pads) * pad is the sink pad (so the same chain function can be used for N pads)
* buf is the buffer being passed */ * buf is the buffer being passed */
typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf); typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf);
typedef GstBuffer *(*GstPadPullFunction) (GstPad *pad);
typedef void (*GstPadPushFunction) (GstPad *pad); typedef void (*GstPadPushFunction) (GstPad *pad);
typedef enum { typedef enum {
@ -77,6 +79,7 @@ struct _GstPad {
GstBuffer *bufpen; GstBuffer *bufpen;
GstPadChainFunction chain; GstPadChainFunction chain;
GstPadPullFunction pull;
GstObject *parent; GstObject *parent;
GList *ghostparents; GList *ghostparents;
@ -92,6 +95,7 @@ void gst_pad_destroy(GstPad *pad);
GstPadDirection gst_pad_get_direction(GstPad *pad); GstPadDirection gst_pad_get_direction(GstPad *pad);
void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain); void gst_pad_set_chain_function(GstPad *pad,GstPadChainFunction chain);
void gst_pad_set_pull_function(GstPad *pad, GstPadPullFunction pull);
guint32 gst_pad_get_type_id(GstPad *pad); guint32 gst_pad_get_type_id(GstPad *pad);
void gst_pad_set_type_id(GstPad *pad,guint16 id); void gst_pad_set_type_id(GstPad *pad,guint16 id);

View file

@ -70,7 +70,7 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
g_return_if_fail(decode_video != NULL); g_return_if_fail(decode_video != NULL);
show = gst_elementfactory_make("videosink","show"); show = gst_elementfactory_make("videosink","show");
g_return_if_fail(show != NULL); g_return_if_fail(show != NULL);
gtk_object_set(GTK_OBJECT(show),"scale",2.0,NULL); //gtk_object_set(GTK_OBJECT(show),"width",640, "height", 480,NULL);
appwindow = gnome_app_new("MPEG1 player","MPEG1 player"); appwindow = gnome_app_new("MPEG1 player","MPEG1 player");
gnome_app_set_contents(GNOME_APP(appwindow), gnome_app_set_contents(GNOME_APP(appwindow),

View file

@ -5,17 +5,22 @@ extern gboolean _gst_plugin_spew;
gboolean idle_func(gpointer data); gboolean idle_func(gpointer data);
GtkWidget *drawingarea; GstElement *src;
void eof(GstSrc *src) { void eof(GstSrc *src) {
g_print("have eos, quitting\n"); g_print("have eos, quitting\n");
exit(0); exit(0);
} }
void resize(GstSink *sink) {
g_print("have resize\n");
gtk_object_set(GTK_OBJECT(src),"width",640,"height",480,NULL);
}
int main(int argc,char *argv[]) { int main(int argc,char *argv[]) {
GstElement *bin; GstElement *bin;
GstElementFactory *srcfactory; GstElementFactory *srcfactory;
GstElement *src;
GstElementFactory *videosinkfactory; GstElementFactory *videosinkfactory;
GstElement *videosink; GstElement *videosink;
@ -37,7 +42,7 @@ int main(int argc,char *argv[]) {
src = gst_elementfactory_create(srcfactory,"src"); src = gst_elementfactory_create(srcfactory,"src");
videosink = gst_elementfactory_create(videosinkfactory,"videosink"); videosink = gst_elementfactory_create(videosinkfactory,"videosink");
gtk_object_set(GTK_OBJECT(videosink),"width",320,"height",240,NULL); gtk_object_set(GTK_OBJECT(videosink),"width",640,"height",480,NULL);
gst_bin_add(GST_BIN(bin),GST_ELEMENT(src)); gst_bin_add(GST_BIN(bin),GST_ELEMENT(src));
@ -50,7 +55,6 @@ int main(int argc,char *argv[]) {
GTK_SIGNAL_FUNC(eof),NULL); GTK_SIGNAL_FUNC(eof),NULL);
appwindow = gnome_app_new("Videotest","Videotest"); appwindow = gnome_app_new("Videotest","Videotest");
drawingarea = gtk_drawing_area_new();
gnome_app_set_contents(GNOME_APP(appwindow), gnome_app_set_contents(GNOME_APP(appwindow),
gst_util_get_widget_arg(GTK_OBJECT(videosink),"widget")); gst_util_get_widget_arg(GTK_OBJECT(videosink),"widget"));
gtk_widget_show_all(appwindow); gtk_widget_show_all(appwindow);