static GstBuffer * gst_file_src_map_region (GstFileSrc * src, off_t offset, gsize size, gboolean testonly) { GstBuffer *buf; void *mmapregion; g_return_val_if_fail (offset >= 0, NULL); /* FIXME ? use goffset and friends if we require glib >= 2.20 */ GST_LOG_OBJECT (src, "mapping region %08" G_GINT64_MODIFIER "x+%08lx " "from file into memory", (gint64) offset, (gulong) size); mmapregion = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset); if (mmapregion == NULL || mmapregion == MAP_FAILED) goto mmap_failed; GST_LOG_OBJECT (src, "mapped region %08lx+%08lx from file into memory at %p", (gulong) offset, (gulong) size, mmapregion); /* time to allocate a new mapbuf */ buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_MMAP_BUFFER); /* mmap() the data into this new buffer */ GST_BUFFER_DATA (buf) = mmapregion; GST_MMAP_BUFFER (buf)->filesrc = src; #ifdef MADV_SEQUENTIAL if (src->sequential) { /* madvise to tell the kernel what to do with it */ if (madvise (mmapregion, size, MADV_SEQUENTIAL) < 0) { GST_WARNING_OBJECT (src, "warning: madvise failed: %s", g_strerror (errno)); } } #endif /* fill in the rest of the fields */ GST_BUFFER_SIZE (buf) = size; GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET_END (buf) = offset + size; GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; return buf; /* ERROR */ mmap_failed: { if (!testonly) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("mmap (0x%08lx, %d, 0x%" G_GINT64_MODIFIER "x) failed: %s", (gulong) size, src->fd, (guint64) offset, g_strerror (errno))); } return NULL; } }
static GstBuffer * gst_file_src_map_region (GstFileSrc * src, off_t offset, gsize size, gboolean testonly) { GstBuffer *buf; void *mmapregion; g_return_val_if_fail (offset >= 0, NULL); GST_LOG_OBJECT (src, "mapping region %08llx+%08lx from file into memory", offset, (gulong) size); mmapregion = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset); if (mmapregion == NULL || mmapregion == MAP_FAILED) goto mmap_failed; GST_LOG_OBJECT (src, "mapped region %08lx+%08lx from file into memory at %p", (gulong) offset, (gulong) size, mmapregion); /* time to allocate a new mapbuf */ buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_MMAP_BUFFER); /* mmap() the data into this new buffer */ GST_BUFFER_DATA (buf) = mmapregion; GST_MMAP_BUFFER (buf)->filesrc = src; #ifdef MADV_SEQUENTIAL if (src->sequential) { /* madvise to tell the kernel what to do with it */ #ifndef __SYMBIAN32__ if (madvise (mmapregion, size, MADV_SEQUENTIAL) < 0) { GST_WARNING_OBJECT (src, "warning: madvise failed: %s", g_strerror (errno)); } #endif #endif /* fill in the rest of the fields */ GST_BUFFER_SIZE (buf) = size; GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET_END (buf) = offset + size; GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; return buf; /* ERROR */ mmap_failed: { if (!testonly) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("mmap (0x%08lx, %d, 0x%" G_GINT64_MODIFIER "x) failed: %s", (gulong) size, src->fd, (guint64) offset, g_strerror (errno))); } return NULL; } } static GstBuffer * gst_file_src_map_small_region (GstFileSrc * src, off_t offset, gsize size) { GstBuffer *ret; off_t mod; guint pagesize; GST_LOG_OBJECT (src, "attempting to map a small buffer at %" G_GUINT64_FORMAT "+%d", (guint64) offset, (gint) size); pagesize = src->pagesize; mod = offset % pagesize; /* if the offset starts at a non-page boundary, we have to special case */ if (mod != 0) { gsize mapsize; off_t mapbase; GstBuffer *map; mapbase = offset - mod; mapsize = ((size + mod + pagesize - 1) / pagesize) * pagesize; GST_LOG_OBJECT (src, "not on page boundaries, resizing to map to %" G_GUINT64_FORMAT "+%d", (guint64) mapbase, (gint) mapsize); map = gst_file_src_map_region (src, mapbase, mapsize, FALSE); if (map == NULL) return NULL; ret = gst_buffer_create_sub (map, offset - mapbase, size); GST_BUFFER_OFFSET (ret) = GST_BUFFER_OFFSET (map) + offset - mapbase; gst_buffer_unref (map); } else { ret = gst_file_src_map_region (src, offset, size, FALSE); } return ret; }