*
* Returns: the current cothread id
*/
+int cothread_getcurrent(void) __attribute__ ((no_instrument_function));
int cothread_getcurrent(void) {
cothread_context *ctx = pthread_getspecific(_cothread_key);
if (!ctx) return -1;
g_return_if_fail (buf != NULL);
aggregator = GST_AGGREGATOR (gst_pad_get_parent (pad));
- gst_trace_add_entry (NULL, 0, buf, "aggregator buffer");
+// gst_trace_add_entry (NULL, 0, buf, "aggregator buffer");
gst_aggregator_push (aggregator, pad, buf, "chain");
}
static void gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static GstBuffer * gst_filesrc_get (GstPad *pad);
+static gboolean gst_filesrc_srcpad_event (GstPad *pad, GstEventType event, gint64 location, guint32 data);
static GstElementStateReturn gst_filesrc_change_state (GstElement *element);
{
src->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (src->srcpad,gst_filesrc_get);
+ gst_pad_set_event_function (src->srcpad,gst_filesrc_srcpad_event);
gst_element_add_pad (GST_ELEMENT (src), src->srcpad);
src->pagesize = getpagesize();
src->curoffset = g_value_get_ulong (value);
break;
case ARG_MAPSIZE:
- src->mapsize = g_value_get_ulong (value);
+ if ((src->mapsize % src->pagesize) == 0)
+ src->mapsize = g_value_get_ulong (value);
+ else
+ GST_INFO(0, "invalid mapsize, must a multiple of pagesize, which is %d\n",src->pagesize);
break;
default:
break;
gst_filesrc_map_region (GstFileSrc *src, off_t offset, off_t size)
{
GstBuffer *buf;
+ gint retval;
- fprintf(stderr,"mapping region %d+%d from file into memory\n",offset,size);
+// fprintf(stderr,"mapping region %d+%d from file into memory\n",offset,size);
// time to allocate a new mapbuf
buf = gst_buffer_new();
GST_BUFFER_DATA(buf) = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset);
if (GST_BUFFER_DATA(buf) == NULL) {
fprintf(stderr, "ERROR: gstfilesrc couldn't map file!\n");
- } else if (GST_BUFFER_DATA(buf) == -1) {
+ } else if (GST_BUFFER_DATA(buf) == (void *)-1) {
perror("gstfilesrc:mmap()");
}
+ // madvise to tell the kernel what to do with it
+ retval = madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_SEQUENTIAL);
// fill in the rest of the fields
GST_BUFFER_FLAGS(buf) = GST_BUFFER_READONLY | GST_BUFFER_ORIGINAL;
GST_BUFFER_SIZE(buf) = size;
{
GstFileSrc *src;
GstBuffer *buf = NULL, *map;
- off_t readend,mapstart,mapend;
+ off_t readend,readsize,mapstart,mapend;
+ gboolean eof = FALSE;
GstFileSrcRegion region;
int i;
src = GST_FILESRC (gst_pad_get_parent (pad));
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL);
- // calculate end poiters so we don't have to do so repeatedly later
+ // calculate end pointers so we don't have to do so repeatedly later
+ readsize = src->block_size;
readend = src->curoffset + src->block_size; // note this is the byte *after* the read
mapstart = GST_BUFFER_OFFSET(src->mapbuf);
mapend = mapstart + GST_BUFFER_SIZE(src->mapbuf); // note this is the byte *after* the map
+ // check to see if we're going to overflow the end of the file
+ if (readend > src->filelen) {
+ readsize = src->filelen - src->curoffset;
+ readend = src->curoffset;
+ eof = TRUE;
+ }
+
// if the start is past the mapstart
if (src->curoffset >= mapstart) {
// if the end is before the mapend, the buffer is in current mmap region...
// ('cause by definition if readend is in the buffer, so's readstart)
if (readend <= mapend) {
// printf("read buf %d+%d lives in current mapbuf %d+%d, creating subbuffer of mapbuf\n",
-// src->curoffset,src->block_size,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+// src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf),
- src->block_size);
+ readsize);
// if the start actually is within the current mmap region, map an overlap buffer
} else if (src->curoffset < mapend) {
// printf("read buf %d+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
-// src->curoffset,src->block_size,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
- buf = gst_filesrc_map_small_region (src, src->curoffset, src->block_size);
+// src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+ buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
}
// the only other option is that buffer is totally outside, which means we search for it
// or the read buffer fully contains the current mmap region
// either way, it's really not relevant, we just create a new region anyway
// printf("read buf %d+%d starts before mapbuf %d+%d, but overlaps it\n",
-// src->curoffset,src->block_size,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
- buf = gst_filesrc_map_small_region (src, src->curoffset, src->block_size);
+// src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+ buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
}
// then deal with the case where the read buffer is totally outside
if (buf == NULL) {
// first check to see if there's a map that covers the right region already
-// printf("searching for mapbuf to cover %d+%d\n",src->curoffset,src->block_size);
+// printf("searching for mapbuf to cover %d+%d\n",src->curoffset,readsize);
region.offset = src->curoffset;
- region.size = src->block_size;
+ region.size = readsize;
map = g_tree_search(src->map_regions,gst_filesrc_search_region_match,®ion);
// if we found an exact match, subbuffer it
if (map != NULL) {
// printf("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
- buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), src->block_size);
+ buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), readsize);
// otherwise we need to create something out of thin air
} else {
// if the read buffer crosses a mmap region boundary, create a one-off region
- if ((src->curoffset / src->mapsize) != ((src->curoffset + src->block_size) / src->mapsize)) {
+ if ((src->curoffset / src->mapsize) != (readend / src->mapsize)) {
// printf("read buf %d+%d crosses a %d-byte boundary, creating a one-off\n",
-// src->curoffset,src->block_size,src->mapsize);
- buf = gst_filesrc_map_small_region (src, src->curoffset, src->block_size);
+// src->curoffset,readsize,src->mapsize);
+ buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
// otherwise we will create a new mmap region and set it to the default
} else {
off_t nextmap = src->curoffset - (src->curoffset % src->mapsize);
// printf("read buf %d+%d in new mapbuf at %d+%d, mapping and subbuffering\n",
-// src->curoffset,src->block_size,nextmap,src->mapsize);
+// src->curoffset,readsize,nextmap,src->mapsize);
// first, we're done with the old mapbuf
gst_buffer_unref(src->mapbuf);
// create a new one
src->mapbuf = gst_filesrc_map_region (src, nextmap, src->mapsize);
// subbuffer it
- buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf), src->block_size);
+ buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf), readsize);
}
}
}
*(GST_BUFFER_DATA(buf)+i) = *(GST_BUFFER_DATA(buf)+i);
}
+ // if we hit EOF,
+
/* we're done, return the buffer */
src->curoffset += GST_BUFFER_SIZE(buf);
return buf;
return GST_STATE_SUCCESS;
}
+
+static gboolean
+gst_filesrc_srcpad_event(GstPad *pad, GstEventType event, gint64 location, guint32 data)
+{
+ GstFileSrc *src = GST_FILESRC(GST_PAD_PARENT(pad));
+
+ if (event == GST_EVENT_SEEK) {
+ if (data == SEEK_SET) {
+ src->curoffset = (guint64)location;
+ } else if (data == SEEK_CUR) {
+ src->curoffset += (gint64)location;
+ } else if (data == SEEK_END) {
+ src->curoffset = src->filelen - (guint64)location;
+ }
+ // push a discontinuous event?
+ return TRUE;
+ }
+
+ return FALSE;
+}
g_return_if_fail (buf != NULL);
tee = GST_TEE (gst_pad_get_parent (pad));
- gst_trace_add_entry (NULL, 0, buf, "tee buffer");
+// gst_trace_add_entry (NULL, 0, buf, "tee buffer");
for (i=0; i<tee->numsrcpads-1; i++)
gst_buffer_ref (buf);
gst_elementfactory_get_type ();
gst_typefactory_get_type ();
+#ifndef GST_DISABLE_AUTOPLUG
gst_autoplugfactory_get_type ();
+#endif
_gst_cpu_initialize ();
_gst_props_initialize ();
*/
//#define GST_DEBUG_ENABLED
-#include "config.h"
#include "gst_private.h"
#include "gstbin.h"
return newbuf;
}
+/*
+ * gst_buffer_is_span_fast
+ * @buf1: first source buffer
+ * @buf2: second source buffer
+ *
+ * Determines whether a gst_buffer_span is free, or requires a memcpy.
+ *
+ * Returns: TRUE if the buffers are contiguous, FALSE if a copy would be required.
+ */
+gboolean
+gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2)
+{
+ return ((buf1->parent == buf2->parent) &&
+ ((buf1->data + buf1->size) == buf2->data));
+}
+
/**
* gst_buffer_span:
}
// if the two buffers have the same parent and are adjacent
- if ((buf1->parent == buf2->parent) &&
- ((buf1->data + buf1->size) == buf2->data)) {
+// if ((buf1->parent == buf2->parent) &&
+// ((buf1->data + buf1->size) == buf2->data)) {
+ if (gst_buffer_is_span_fast(buf1,buf2)) {
// we simply create a subbuffer of the common parent
return gst_buffer_create_sub(buf1->parent, buf1->data - (buf1->parent->data) + offset, len);
}
GstBuffer* gst_buffer_span (GstBuffer *buf1,guint32 offset,GstBuffer *buf2,guint32 len);
GstBuffer* gst_buffer_append (GstBuffer *buf, GstBuffer *buf2);
+gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
return FALSE;
}
+#if (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) )
/**
* gst_caps_save_thyself:
* @caps: a capabilty to save
return result;
}
+
+#endif /* (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) ) */
static void gst_elementfactory_class_init (GstElementFactoryClass *klass);
static void gst_elementfactory_init (GstElementFactory *factory);
+#ifndef GST_DISABLE_REGISTRY
static void gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
static xmlNodePtr gst_elementfactory_save_thyself (GstObject *object, xmlNodePtr parent);
+#endif /* GST_DISABLE_REGISTRY */
static void gst_elementfactory_unload_thyself (GstPluginFeature *feature);
parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
+#ifndef GST_DISABLE_REGISTRY
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_restore_thyself);
+#endif /* GST_DISABLE_REGISTRY */
gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_elementfactory_unload_thyself);
factory->type = 0;
}
+#ifndef GST_DISABLE_REGISTRY
static xmlNodePtr
gst_elementfactory_save_thyself (GstObject *object,
xmlNodePtr parent)
children = children->next;
}
}
+#endif /* GST_DISABLE_REGISTRY */
GST_EVENT_EOS,
GST_EVENT_FLUSH,
GST_EVENT_EMPTY,
+ GST_EVENT_SEEK,
} GstEventType;
typedef struct _GstEvent GstEvent;
"REFCOUNTING",
"EVENT",
"PARAMS",
+
+ [30] = "CALL_TRACE",
};
/**
[GST_CAT_EVENT] = "01;37;41", // !!
[GST_CAT_PARAMS] = "00;30;43", // !!
- [31] = "",
+ [GST_CAT_CALL_TRACE] = "",
};
/* colorization hash - DEPRACATED in favor of above */
const gchar *file, const gchar *function,
gint line, const gchar *debug_string,
void *element, gchar *string)
+ __attribute__ ((no_instrument_function));
+
+void
+gst_default_debug_handler (gint category, gboolean incore,
+ const gchar *file, const gchar *function,
+ gint line, const gchar *debug_string,
+ void *element, gchar *string)
{
gchar *empty = "";
gchar *elementname = empty,*location = empty;
/***** DEBUG system *****/
GHashTable *__gst_function_pointers = NULL;
+gchar *_gst_debug_nameof_funcptr (void *ptr) __attribute__ ((no_instrument_function));
+
gchar *
_gst_debug_nameof_funcptr (void *ptr)
{
gchar *ptrname;
Dl_info dlinfo;
- if (__gst_function_pointers) {
- if ((ptrname = g_hash_table_lookup(__gst_function_pointers,ptr)))
- return g_strdup(ptrname);
+ if (__gst_function_pointers && (ptrname = g_hash_table_lookup(__gst_function_pointers,ptr))) {
+ return g_strdup(ptrname);
} else if (dladdr(ptr,&dlinfo) && dlinfo.dli_sname) {
return g_strdup(dlinfo.dli_sname);
} else {
}
return NULL;
}
+
+
+#ifdef GST_ENABLE_FUNC_INSTRUMENTATION
+
+void __cyg_profile_func_enter(void *this_fn,void *call_site) __attribute__ ((no_instrument_function));
+void __cyg_profile_func_enter(void *this_fn,void *call_site) {
+ GST_DEBUG(GST_CAT_CALL_TRACE, "entering function %s\n", _gst_debug_nameof_funcptr (this_fn));
+}
+
+void __cyg_profile_func_exit(void *this_fn,void *call_site) __attribute__ ((no_instrument_function));
+void __cyg_profile_func_exit(void *this_fn,void *call_site) {
+ GST_DEBUG(GST_CAT_CALL_TRACE, "leavinging function %s\n", _gst_debug_nameof_funcptr (this_fn));
+}
+
+#endif /* GST_ENABLE_FUNC_INTSTRUMENTATION */
GST_CAT_REFCOUNTING, // Ref Counting stuff
GST_CAT_EVENT, // Event system
GST_CAT_PARAMS, // Dynamic parameters
-
+
+ GST_CAT_CALL_TRACE = 30, // Call tracing
+
GST_CAT_MAX_CATEGORY = 31
};
return GST_PADTEMPLATE_CAPS (templ);
}
+#ifndef GST_DISABLE_LOADSAVE
/**
* gst_padtemplate_save_thyself:
* @templ: the padtemplate to save
return factory;
}
+#endif /* !GST_DISABLE_LOADSAVE */
/**
static void gst_plugin_feature_class_init (GstPluginFeatureClass *klass);
static void gst_plugin_feature_init (GstPluginFeature *feature);
+#ifndef GST_DISABLE_REGISTRY
static xmlNodePtr gst_plugin_feature_save_thyself (GstObject *object, xmlNodePtr parent);
static void gst_plugin_feature_restore_thyself (GstObject *object, xmlNodePtr parent);
+#endif /* GST_DISABLE_REGISTRY */
static GstObjectClass *parent_class = NULL;
//static guint gst_plugin_feature_signals[LAST_SIGNAL] = { 0 };
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
+#ifndef GST_DISABLE_REGISTRY
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_plugin_feature_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_plugin_feature_restore_thyself);
+#endif /* GST_DISABLE_REGISTRY */
}
static void
feature->manager = NULL;
}
+#ifndef GST_DISABLE_REGISTRY
static xmlNodePtr
gst_plugin_feature_save_thyself (GstObject *object, xmlNodePtr parent)
{
field = field->next;
}
}
+#endif /* GST_DISABLE_REGISTRY */
void
gst_plugin_feature_ensure_loaded (GstPluginFeature *feature)
return compatible;
}
+#if (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) )
static xmlNodePtr
gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
{
return props;
}
+#endif /* (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) ) */
+
static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv);
+#ifndef GST_DISABLE_REGISTRY
static xmlNodePtr gst_typefactory_save_thyself (GstObject *object, xmlNodePtr parent);
static void gst_typefactory_restore_thyself (GstObject *object, xmlNodePtr parent);
+#endif /* GST_DISABLE_REGISTRY */
static void gst_typefactory_unload_thyself (GstPluginFeature *feature);
parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
+#ifndef GST_DISABLE_REGISTRY
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_restore_thyself);
+#endif /* GST_DISABLE_REGISTRY */
gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_typefactory_unload_thyself);
factory->typefindfunc = gst_type_typefind_dummy;
}
+static GstCaps*
+gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv)
+{
+ GstTypeFactory *factory = (GstTypeFactory *)priv;
+
+ GST_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s\n", factory->mime);
+
+ gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory));
+
+ if (factory->typefindfunc) {
+ GstCaps *res = factory->typefindfunc (buffer, factory);
+ if (res)
+ return res;
+ }
+
+ return NULL;
+}
+
+#ifndef GST_DISABLE_REGISTRY
static xmlNodePtr
gst_typefactory_save_thyself (GstObject *object, xmlNodePtr parent)
{
return parent;
}
-static GstCaps*
-gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv)
-{
- GstTypeFactory *factory = (GstTypeFactory *)priv;
-
- GST_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s\n", factory->mime);
-
- gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory));
-
- if (factory->typefindfunc) {
- GstCaps *res = factory->typefindfunc (buffer, factory);
- if (res)
- return res;
- }
-
- return NULL;
-}
-
/**
* gst_typefactory_restore_thyself:
* @parent: the parent node to load from
gst_type_register (factory);
}
-
+#endif /* GST_DISABLE_REGISTRY */
g_return_if_fail (buf != NULL);
aggregator = GST_AGGREGATOR (gst_pad_get_parent (pad));
- gst_trace_add_entry (NULL, 0, buf, "aggregator buffer");
+// gst_trace_add_entry (NULL, 0, buf, "aggregator buffer");
gst_aggregator_push (aggregator, pad, buf, "chain");
}
static void gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static GstBuffer * gst_filesrc_get (GstPad *pad);
+static gboolean gst_filesrc_srcpad_event (GstPad *pad, GstEventType event, gint64 location, guint32 data);
static GstElementStateReturn gst_filesrc_change_state (GstElement *element);
{
src->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (src->srcpad,gst_filesrc_get);
+ gst_pad_set_event_function (src->srcpad,gst_filesrc_srcpad_event);
gst_element_add_pad (GST_ELEMENT (src), src->srcpad);
src->pagesize = getpagesize();
src->curoffset = g_value_get_ulong (value);
break;
case ARG_MAPSIZE:
- src->mapsize = g_value_get_ulong (value);
+ if ((src->mapsize % src->pagesize) == 0)
+ src->mapsize = g_value_get_ulong (value);
+ else
+ GST_INFO(0, "invalid mapsize, must a multiple of pagesize, which is %d\n",src->pagesize);
break;
default:
break;
gst_filesrc_map_region (GstFileSrc *src, off_t offset, off_t size)
{
GstBuffer *buf;
+ gint retval;
- fprintf(stderr,"mapping region %d+%d from file into memory\n",offset,size);
+// fprintf(stderr,"mapping region %d+%d from file into memory\n",offset,size);
// time to allocate a new mapbuf
buf = gst_buffer_new();
GST_BUFFER_DATA(buf) = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset);
if (GST_BUFFER_DATA(buf) == NULL) {
fprintf(stderr, "ERROR: gstfilesrc couldn't map file!\n");
- } else if (GST_BUFFER_DATA(buf) == -1) {
+ } else if (GST_BUFFER_DATA(buf) == (void *)-1) {
perror("gstfilesrc:mmap()");
}
+ // madvise to tell the kernel what to do with it
+ retval = madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_SEQUENTIAL);
// fill in the rest of the fields
GST_BUFFER_FLAGS(buf) = GST_BUFFER_READONLY | GST_BUFFER_ORIGINAL;
GST_BUFFER_SIZE(buf) = size;
{
GstFileSrc *src;
GstBuffer *buf = NULL, *map;
- off_t readend,mapstart,mapend;
+ off_t readend,readsize,mapstart,mapend;
+ gboolean eof = FALSE;
GstFileSrcRegion region;
int i;
src = GST_FILESRC (gst_pad_get_parent (pad));
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL);
- // calculate end poiters so we don't have to do so repeatedly later
+ // calculate end pointers so we don't have to do so repeatedly later
+ readsize = src->block_size;
readend = src->curoffset + src->block_size; // note this is the byte *after* the read
mapstart = GST_BUFFER_OFFSET(src->mapbuf);
mapend = mapstart + GST_BUFFER_SIZE(src->mapbuf); // note this is the byte *after* the map
+ // check to see if we're going to overflow the end of the file
+ if (readend > src->filelen) {
+ readsize = src->filelen - src->curoffset;
+ readend = src->curoffset;
+ eof = TRUE;
+ }
+
// if the start is past the mapstart
if (src->curoffset >= mapstart) {
// if the end is before the mapend, the buffer is in current mmap region...
// ('cause by definition if readend is in the buffer, so's readstart)
if (readend <= mapend) {
// printf("read buf %d+%d lives in current mapbuf %d+%d, creating subbuffer of mapbuf\n",
-// src->curoffset,src->block_size,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+// src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf),
- src->block_size);
+ readsize);
// if the start actually is within the current mmap region, map an overlap buffer
} else if (src->curoffset < mapend) {
// printf("read buf %d+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
-// src->curoffset,src->block_size,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
- buf = gst_filesrc_map_small_region (src, src->curoffset, src->block_size);
+// src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+ buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
}
// the only other option is that buffer is totally outside, which means we search for it
// or the read buffer fully contains the current mmap region
// either way, it's really not relevant, we just create a new region anyway
// printf("read buf %d+%d starts before mapbuf %d+%d, but overlaps it\n",
-// src->curoffset,src->block_size,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
- buf = gst_filesrc_map_small_region (src, src->curoffset, src->block_size);
+// src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+ buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
}
// then deal with the case where the read buffer is totally outside
if (buf == NULL) {
// first check to see if there's a map that covers the right region already
-// printf("searching for mapbuf to cover %d+%d\n",src->curoffset,src->block_size);
+// printf("searching for mapbuf to cover %d+%d\n",src->curoffset,readsize);
region.offset = src->curoffset;
- region.size = src->block_size;
+ region.size = readsize;
map = g_tree_search(src->map_regions,gst_filesrc_search_region_match,®ion);
// if we found an exact match, subbuffer it
if (map != NULL) {
// printf("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
- buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), src->block_size);
+ buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), readsize);
// otherwise we need to create something out of thin air
} else {
// if the read buffer crosses a mmap region boundary, create a one-off region
- if ((src->curoffset / src->mapsize) != ((src->curoffset + src->block_size) / src->mapsize)) {
+ if ((src->curoffset / src->mapsize) != (readend / src->mapsize)) {
// printf("read buf %d+%d crosses a %d-byte boundary, creating a one-off\n",
-// src->curoffset,src->block_size,src->mapsize);
- buf = gst_filesrc_map_small_region (src, src->curoffset, src->block_size);
+// src->curoffset,readsize,src->mapsize);
+ buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
// otherwise we will create a new mmap region and set it to the default
} else {
off_t nextmap = src->curoffset - (src->curoffset % src->mapsize);
// printf("read buf %d+%d in new mapbuf at %d+%d, mapping and subbuffering\n",
-// src->curoffset,src->block_size,nextmap,src->mapsize);
+// src->curoffset,readsize,nextmap,src->mapsize);
// first, we're done with the old mapbuf
gst_buffer_unref(src->mapbuf);
// create a new one
src->mapbuf = gst_filesrc_map_region (src, nextmap, src->mapsize);
// subbuffer it
- buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf), src->block_size);
+ buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf), readsize);
}
}
}
*(GST_BUFFER_DATA(buf)+i) = *(GST_BUFFER_DATA(buf)+i);
}
+ // if we hit EOF,
+
/* we're done, return the buffer */
src->curoffset += GST_BUFFER_SIZE(buf);
return buf;
return GST_STATE_SUCCESS;
}
+
+static gboolean
+gst_filesrc_srcpad_event(GstPad *pad, GstEventType event, gint64 location, guint32 data)
+{
+ GstFileSrc *src = GST_FILESRC(GST_PAD_PARENT(pad));
+
+ if (event == GST_EVENT_SEEK) {
+ if (data == SEEK_SET) {
+ src->curoffset = (guint64)location;
+ } else if (data == SEEK_CUR) {
+ src->curoffset += (gint64)location;
+ } else if (data == SEEK_END) {
+ src->curoffset = src->filelen - (guint64)location;
+ }
+ // push a discontinuous event?
+ return TRUE;
+ }
+
+ return FALSE;
+}
g_return_if_fail (buf != NULL);
tee = GST_TEE (gst_pad_get_parent (pad));
- gst_trace_add_entry (NULL, 0, buf, "tee buffer");
+// gst_trace_add_entry (NULL, 0, buf, "tee buffer");
for (i=0; i<tee->numsrcpads-1; i++)
gst_buffer_ref (buf);