From c17ed10404e37b2be079a4fa78060420f7b4786f Mon Sep 17 00:00:00 2001 From: Erik Walthinsen Date: Mon, 5 Feb 2001 17:16:23 +0000 Subject: [PATCH] Reworked getregion/pullregion stuff. Region is now specified by a type (OFFSET_LEN, TIME_LEN, etc.) and two guint64'... Original commit message from CVS: Reworked getregion/pullregion stuff. Region is now specified by a type (OFFSET_LEN, TIME_LEN, etc.) and two guint64's. They are offset and len, where offset can be used for the time field, and len would be zero or the time unit (say, 33ms for video). --- gst/elements/gstdisksrc.c | 21 ++++---- gst/gstinfo.h | 2 +- gst/gstpad.c | 6 +-- gst/gstpad.h | 25 ++++++--- gst/gstscheduler.c | 99 +++++++++++++++++++++-------------- plugins/elements/gstdisksrc.c | 21 ++++---- 6 files changed, 104 insertions(+), 70 deletions(-) diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c index 0703076507..94f1a162a7 100644 --- a/gst/elements/gstdisksrc.c +++ b/gst/elements/gstdisksrc.c @@ -56,14 +56,14 @@ enum { }; -static void gst_disksrc_class_init (GstDiskSrcClass *klass); -static void gst_disksrc_init (GstDiskSrc *disksrc); +static void gst_disksrc_class_init (GstDiskSrcClass *klass); +static void gst_disksrc_init (GstDiskSrc *disksrc); -static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); -static GstBuffer * gst_disksrc_get (GstPad *pad); -static GstBuffer * gst_disksrc_get_region (GstPad *pad, gulong offset, gulong size); +static GstBuffer * gst_disksrc_get (GstPad *pad); +static GstBuffer * gst_disksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); static GstElementStateReturn gst_disksrc_change_state (GstElement *element); @@ -269,12 +269,13 @@ gst_disksrc_get (GstPad *pad) * Push a new buffer from the disksrc of given size at given offset. */ static GstBuffer * -gst_disksrc_get_region (GstPad *pad, gulong offset, gulong size) +gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len) { GstDiskSrc *src; GstBuffer *buf; g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (type == GST_REGION_OFFSET_LEN, NULL); src = GST_DISKSRC (gst_pad_get_parent (pad)); @@ -297,13 +298,13 @@ gst_disksrc_get_region (GstPad *pad, gulong offset, gulong size) GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); - if ((offset + size) > src->size) { + if ((offset + len) > src->size) { GST_BUFFER_SIZE (buf) = src->size - offset; // FIXME: set the buffer's EOF bit here } else - GST_BUFFER_SIZE (buf) = size; + GST_BUFFER_SIZE (buf) = len; - GST_DEBUG (0,"map %p, offset %ld, size %d\n", src->map, offset, GST_BUFFER_SIZE (buf)); + GST_DEBUG (0,"map %p, offset %lld, size %d\n", src->map, offset, GST_BUFFER_SIZE (buf)); /* we're done, return the buffer off now */ return buf; diff --git a/gst/gstinfo.h b/gst/gstinfo.h index 69abbe374f..cb11ca1ead 100644 --- a/gst/gstinfo.h +++ b/gst/gstinfo.h @@ -261,7 +261,7 @@ enum { GST_CAT_STATES, // State changes and such GST_CAT_PLANNING, // Plan generation GST_CAT_SCHEDULING, // Schedule construction - GST_CAT_OPERATION, // Events during actual data movement + GST_CAT_DATAFLOW, // Events during actual data movement GST_CAT_BUFFER, // Buffer creation/destruction GST_CAT_CAPS, // Capabilities matching GST_CAT_CLOCK, // Clocking diff --git a/gst/gstpad.c b/gst/gstpad.c index 4bd07bdfd9..954fbc5c66 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -937,13 +937,13 @@ GstBuffer *gst_pad_pull(GstPad *pad) { #endif #ifndef gst_pad_pullregion -GstBuffer *gst_pad_pullregion(GstPad *pad,gulong offset,gulong size) { +GstBuffer *gst_pad_pullregion(GstPad *pad,GstRegionType type,guint64 offset,guint64 len) { GstRealPad *peer = GST_RPAD_PEER(pad); - GST_DEBUG_ENTER("(%s:%s,%ld,%ld)",GST_DEBUG_PAD_NAME(pad),offset,size); + GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len); if (peer->pullregionfunc) { GST_DEBUG (0,"calling pullregionfunc &%s of peer pad %s:%s\n", GST_DEBUG_FUNCPTR_NAME(peer->pullregionfunc),GST_DEBUG_PAD_NAME(((GstPad*)peer))); - return (peer->pullregionfunc)(((GstPad*)peer),offset,size); + return (peer->pullregionfunc)(((GstPad*)peer),type,offset,len); } else { GST_DEBUG (0,"no pullregionfunc\n"); return NULL; diff --git a/gst/gstpad.h b/gst/gstpad.h index 826ea65d76..7fa1fd3b30 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -66,18 +66,24 @@ typedef struct _GstPadTemplate GstPadTemplate; typedef struct _GstPadTemplateClass GstPadTemplateClass; +typedef enum { + GST_REGION_NONE, + GST_REGION_OFFSET_LEN, + GST_REGION_TIME_LEN, +} GstRegionType; + + /* this defines the functions used to chain buffers * pad is the sink pad (so the same chain function can be used for N pads) * buf is the buffer being passed */ typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf); typedef GstBuffer *(*GstPadGetFunction) (GstPad *pad); -typedef GstBuffer *(*GstPadGetRegionFunction) (GstPad *pad, gulong offset, gulong size); +typedef GstBuffer *(*GstPadGetRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); typedef void (*GstPadQoSFunction) (GstPad *pad, glong qos_message); typedef void (*GstPadPushFunction) (GstPad *pad, GstBuffer *buf); typedef GstBuffer *(*GstPadPullFunction) (GstPad *pad); -typedef GstBuffer *(*GstPadPullRegionFunction) (GstPad *pad, gulong offset, gulong size); - +typedef GstBuffer *(*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); typedef gboolean (*GstPadEOSFunction) (GstPad *pad); typedef enum { @@ -116,6 +122,9 @@ struct _GstRealPad { GstRealPad *peer; GstBuffer *bufpen; + GstRegionType regiontype; + guint64 offset; + guint64 len; GstPadChainFunction chainfunc; GstPadGetFunction getfunc; @@ -171,6 +180,10 @@ struct _GstGhostPadClass { #define GST_RPAD_QOSFUNC(pad) (((GstRealPad *)(pad))->qosfunc) #define GST_RPAD_EOSFUNC(pad) (((GstRealPad *)(pad))->eosfunc) +#define GST_RPAD_REGIONTYPE(pad) (((GstRealPad *)(pad))->regiontype) +#define GST_RPAD_OFFSET(pad) (((GstRealPad *)(pad))->offset) +#define GST_RPAD_LEN(pad) (((GstRealPad *)(pad))->len) + /* GstGhostPad */ #define GST_GPAD_REALPAD(pad) (((GstGhostPad *)(pad))->realpad) @@ -277,12 +290,12 @@ void gst_pad_push (GstPad *pad, GstBuffer *buffer); #endif #if 1 GstBuffer* gst_pad_pull (GstPad *pad); -GstBuffer* gst_pad_pull_region (GstPad *pad, gulong offset, gulong size); +GstBuffer* gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); #else #define gst_pad_pull(pad) \ (((pad)->peer->pullfunc) ? ((pad)->peer->pullfunc)((pad)->peer) : NULL) -#define gst_pad_pullregion(pad,offset,size) \ - (((pad)->peer->pullregionfunc) ? ((pad)->peer->pullregionfunc)((pad)->peer,(offset),(size)) : NULL) +#define gst_pad_pullregion(pad,type,offset,len) \ + (((pad)->peer->pullregionfunc) ? ((pad)->peer->pullregionfunc)((pad)->peer,(type),(offset),(len)) : NULL) #endif GstPad * gst_pad_select (GstPad *nextpad, ...); diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index 5f9ad74403..b2230b2fa5 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -86,7 +86,7 @@ gst_bin_src_wrapper (int argc,char *argv[]) GstElement *element = GST_ELEMENT (argv); GList *pads; GstRealPad *realpad; - GstBuffer *buf; + GstBuffer *buf = NULL; G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element); GST_DEBUG_ENTER("(%d,\"%s\")",argc,name); @@ -98,18 +98,20 @@ gst_bin_src_wrapper (int argc,char *argv[]) realpad = (GstRealPad*)(pads->data); pads = g_list_next(pads); if (GST_RPAD_DIRECTION(realpad) == GST_PAD_SRC) { -// region_struct *region = cothread_get_data (element->threadstate, "region"); GST_DEBUG (0,"calling _getfunc for %s:%s\n",GST_DEBUG_PAD_NAME(realpad)); -// if (region) { -// gst_src_push_region (GST_SRC (element), region->offset, region->size); + if (realpad->regiontype != GST_REGION_NONE) { + g_return_val_if_fail (GST_RPAD_GETREGIONFUNC(realpad) != NULL, 0); // if (GST_RPAD_GETREGIONFUNC(realpad) == NULL) // fprintf(stderr,"error, no getregionfunc in \"%s\"\n", name); -// buf = (GST_RPAD_GETREGIONFUNC(realpad))((GstPad*)realpad, region->offset, region->size); -// } else { - if (GST_RPAD_GETFUNC(realpad) == NULL) - fprintf(stderr,"error, no getfunc in \"%s\"\n", name); +// else + buf = (GST_RPAD_GETREGIONFUNC(realpad))((GstPad*)realpad,realpad->regiontype,realpad->offset,realpad->len); + } else { + g_return_val_if_fail (GST_RPAD_GETFUNC(realpad) != NULL, 0); +// if (GST_RPAD_GETFUNC(realpad) == NULL) +// fprintf(stderr,"error, no getfunc in \"%s\"\n", name); +// else buf = GST_RPAD_GETFUNC(realpad) ((GstPad*)realpad); -// } + } GST_DEBUG (0,"calling gst_pad_push on pad %s:%s\n",GST_DEBUG_PAD_NAME(realpad)); if (buf) gst_pad_push ((GstPad*)realpad, buf); @@ -127,11 +129,21 @@ gst_bin_pushfunc_proxy (GstPad *pad, GstBuffer *buf) { cothread_state *threadstate = GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate; GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad)); - GST_DEBUG (0,"putting buffer %p in peer's pen\n",buf); + GST_DEBUG (GST_CAT_DATAFLOW,"putting buffer %p in peer's pen\n",buf); + + // FIXME this should be bounded + // loop until the bufferpen is empty so we can fill it up again + while (GST_RPAD_BUFPEN(pad) != NULL) { + GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to empty bufpen\n",threadstate); + cothread_switch (threadstate); + } + + // now fill the bufferpen and switch so it can be consumed GST_RPAD_BUFPEN(GST_RPAD_PEER(pad)) = buf; - GST_DEBUG (0,"switching to %p (@%p)\n",threadstate,&(GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate)); + GST_DEBUG (GST_CAT_DATAFLOW,"switching to %p (@%p)\n",threadstate,&(GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate)); cothread_switch (threadstate); - GST_DEBUG (0,"done switching\n"); + + GST_DEBUG (GST_CAT_DATAFLOW,"done switching\n"); } static GstBuffer* @@ -141,43 +153,46 @@ gst_bin_pullfunc_proxy (GstPad *pad) cothread_state *threadstate = GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate; GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad)); - // FIXME this should be a while - if (GST_RPAD_BUFPEN(pad) == NULL) { - GST_DEBUG (0,"switching to %p (@%p)\n",threadstate,&(GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate)); + + // FIXME this should be bounded + // we will loop switching to the peer until it's filled up the bufferpen + while (GST_RPAD_BUFPEN(pad) == NULL) { + GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to fill bufpen\n",threadstate); cothread_switch (threadstate); } - GST_DEBUG (0,"done switching\n"); + GST_DEBUG (GST_CAT_DATAFLOW,"done switching\n"); + + // now grab the buffer from the pen, clear the pen, and return the buffer buf = GST_RPAD_BUFPEN(pad); GST_RPAD_BUFPEN(pad) = NULL; return buf; } -static GstBuffer * -gst_bin_chainfunc_proxy (GstPad *pad) +static GstBuffer* +gst_bin_pullregionfunc_proxy (GstPad *pad,GstRegionType type,guint64 offset,guint64 len) { -// FIXME!! -// GstBuffer *buf; - return NULL; -} + GstBuffer *buf; -// FIXME!!! -static void -gst_bin_pullregionfunc_proxy (GstPad *pad, - gulong offset, - gulong size) -{ -// region_struct region; - cothread_state *threadstate; + cothread_state *threadstate = GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate; + GST_DEBUG_ENTER("%s:%s,%d,%lld,%lld",GST_DEBUG_PAD_NAME(pad),type,offset,len); - GST_DEBUG_ENTER("%s:%s,%ld,%ld",GST_DEBUG_PAD_NAME(pad),offset,size); + // put the region info into the pad + GST_RPAD_REGIONTYPE(pad) = type; + GST_RPAD_OFFSET(pad) = offset; + GST_RPAD_LEN(pad) = len; -// region.offset = offset; -// region.size = size; + // FIXME this should be bounded + // we will loop switching to the peer until it's filled up the bufferpen + while (GST_RPAD_BUFPEN(pad) == NULL) { + GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to fill bufpen\n",threadstate); + cothread_switch (threadstate); + } + GST_DEBUG (GST_CAT_DATAFLOW,"done switching\n"); -// threadstate = GST_ELEMENT(pad->parent)->threadstate; -// cothread_set_data (threadstate, "region", ®ion); - cothread_switch (threadstate); -// cothread_set_data (threadstate, "region", NULL); + // now grab the buffer from the pen, clear the pen, and return the buffer + buf = GST_RPAD_BUFPEN(pad); + GST_RPAD_BUFPEN(pad) = NULL; + return buf; } @@ -253,6 +268,7 @@ gst_schedule_cothreaded_chain (GstBin *bin, _GstBinChain *chain) { } else { GST_DEBUG (0,"setting cothreaded pull proxy for srcpad %s:%s\n",GST_DEBUG_PAD_NAME(pad)); GST_RPAD_PULLFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy); + GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy); } } } @@ -496,7 +512,8 @@ void gst_bin_schedule_func(GstBin *bin) { // pad->pullfunc = pad->peer->pullfunc; // GST_DEBUG (0,"PUNT: setting pushfunc proxy to fake proxy on %s:%s\n",GST_DEBUG_PAD_NAME(pad->peer)); // pad->peer->pushfunc = GST_DEBUG_FUNCPTR(gst_bin_pushfunc_fake_proxy); - pad->pullfunc = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy); + GST_RPAD_PULLFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy); + GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy); } } else { */ @@ -525,7 +542,8 @@ void gst_bin_schedule_func(GstBin *bin) { } else if (gst_pad_get_direction (pad) == GST_PAD_SRC) { GST_DEBUG (0,"setting pull proxies for srcpad %s:%s\n",GST_DEBUG_PAD_NAME(pad)); // set the proxy functions - pad->pullfunc = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy); + GST_RPAD_PULLFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy); + GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy); GST_DEBUG (0,"pad->pullfunc(@%p) = gst_bin_pullfunc_proxy(@%p)\n", &pad->pullfunc,gst_bin_pullfunc_proxy); pad->pullregionfunc = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy); @@ -662,7 +680,8 @@ void gst_bin_schedule_func(GstBin *bin) { pad->pushfunc = GST_DEBUG_FUNCPTR(gst_bin_pushfunc_proxy); } else if (gst_pad_get_direction (pad) == GST_PAD_SRC) { GST_DEBUG (0,"setting pull proxy for srcpad %s:%s\n",GST_DEBUG_PAD_NAME(pad)); - pad->pullfunc = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy); + GST_RPAD_PULLFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy); + GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy); } } else { // otherwise we need to set up for 'traditional' chaining diff --git a/plugins/elements/gstdisksrc.c b/plugins/elements/gstdisksrc.c index 0703076507..94f1a162a7 100644 --- a/plugins/elements/gstdisksrc.c +++ b/plugins/elements/gstdisksrc.c @@ -56,14 +56,14 @@ enum { }; -static void gst_disksrc_class_init (GstDiskSrcClass *klass); -static void gst_disksrc_init (GstDiskSrc *disksrc); +static void gst_disksrc_class_init (GstDiskSrcClass *klass); +static void gst_disksrc_init (GstDiskSrc *disksrc); -static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); -static GstBuffer * gst_disksrc_get (GstPad *pad); -static GstBuffer * gst_disksrc_get_region (GstPad *pad, gulong offset, gulong size); +static GstBuffer * gst_disksrc_get (GstPad *pad); +static GstBuffer * gst_disksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); static GstElementStateReturn gst_disksrc_change_state (GstElement *element); @@ -269,12 +269,13 @@ gst_disksrc_get (GstPad *pad) * Push a new buffer from the disksrc of given size at given offset. */ static GstBuffer * -gst_disksrc_get_region (GstPad *pad, gulong offset, gulong size) +gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len) { GstDiskSrc *src; GstBuffer *buf; g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (type == GST_REGION_OFFSET_LEN, NULL); src = GST_DISKSRC (gst_pad_get_parent (pad)); @@ -297,13 +298,13 @@ gst_disksrc_get_region (GstPad *pad, gulong offset, gulong size) GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); - if ((offset + size) > src->size) { + if ((offset + len) > src->size) { GST_BUFFER_SIZE (buf) = src->size - offset; // FIXME: set the buffer's EOF bit here } else - GST_BUFFER_SIZE (buf) = size; + GST_BUFFER_SIZE (buf) = len; - GST_DEBUG (0,"map %p, offset %ld, size %d\n", src->map, offset, GST_BUFFER_SIZE (buf)); + GST_DEBUG (0,"map %p, offset %lld, size %d\n", src->map, offset, GST_BUFFER_SIZE (buf)); /* we're done, return the buffer off now */ return buf;