From 8f36390edaedcd8da63fd1feca0675945c41537d Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 30 Jul 2003 00:44:58 +0000 Subject: [PATCH] Implement read() as a fallback method if mmap() fails. Fixes #117786 Original commit message from CVS: Implement read() as a fallback method if mmap() fails. Fixes #117786 --- gst/elements/gstfilesrc.c | 118 +++++++++++++++++++++++++++++------------- plugins/elements/gstfilesrc.c | 118 +++++++++++++++++++++++++++++------------- 2 files changed, 162 insertions(+), 74 deletions(-) diff --git a/gst/elements/gstfilesrc.c b/gst/elements/gstfilesrc.c index 23715a3..066da9e 100644 --- a/gst/elements/gstfilesrc.c +++ b/gst/elements/gstfilesrc.c @@ -402,7 +402,7 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size) return NULL; } else if (mmapregion == MAP_FAILED) { - gst_element_error (GST_ELEMENT (src), "mmap (0x%x, %d, 0x%llx) : %s", + GST_DEBUG ("mmap (0x%x, %d, 0x%llx) : %s", size, src->fd, offset, strerror (errno)); return NULL; } @@ -486,50 +486,20 @@ gst_filesrc_search_region_match (gpointer a, gpointer b) } /** - * gst_filesrc_get: + * gst_filesrc_get_mmap: * @pad: #GstPad to push a buffer from * * Push a new buffer from the filesrc at the current offset. */ static GstBuffer * -gst_filesrc_get (GstPad *pad) +gst_filesrc_get_mmap (GstFileSrc *src) { - GstFileSrc *src; GstBuffer *buf = NULL, *map; size_t readsize, mapsize; off_t readend,mapstart,mapend; GstFileSrcRegion region; int i; - g_return_val_if_fail (pad != NULL, NULL); - src = GST_FILESRC (gst_pad_get_parent (pad)); - g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL); - - /* check for seek */ - if (src->seek_happened) { - GstEvent *event; - - src->seek_happened = FALSE; - GST_DEBUG ("filesrc sending discont"); - event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL); - src->need_flush = FALSE; - return GST_BUFFER (event); - } - /* check for flush */ - if (src->need_flush) { - src->need_flush = FALSE; - GST_DEBUG ("filesrc sending flush"); - return GST_BUFFER (gst_event_new_flush ()); - } - - /* check for EOF */ - if (src->curoffset == src->filelen) { - GST_DEBUG ("filesrc eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT, - src->curoffset, src->filelen); - gst_element_set_eos (GST_ELEMENT (src)); - return GST_BUFFER (gst_event_new (GST_EVENT_EOS)); - } - /* 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 */ @@ -649,6 +619,78 @@ gst_filesrc_get (GstPad *pad) return buf; } +static GstBuffer * +gst_filesrc_get_read (GstFileSrc *src) +{ + GstBuffer *buf = NULL; + size_t readsize; + int ret; + + readsize = src->block_size; + if (src->curoffset + readsize > src->filelen) { + readsize = src->filelen - src->curoffset; + } + + buf = gst_buffer_new_and_alloc (readsize); + g_return_val_if_fail (buf != NULL, NULL); + + ret = read (src->fd, GST_BUFFER_DATA (buf), readsize); + if (ret < 0){ + gst_element_error (GST_ELEMENT (src), "reading file (%s)", + strerror (errno), NULL); + return NULL; + } + if (ret < readsize) { + gst_element_error (GST_ELEMENT (src), "unexpected end of file", NULL); + return NULL; + } + + src->curoffset += readsize; + + return buf; +} + +static GstBuffer * +gst_filesrc_get (GstPad *pad) +{ + GstFileSrc *src; + + g_return_val_if_fail (pad != NULL, NULL); + src = GST_FILESRC (gst_pad_get_parent (pad)); + g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL); + + /* check for seek */ + if (src->seek_happened) { + GstEvent *event; + + src->seek_happened = FALSE; + GST_DEBUG ("filesrc sending discont"); + event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL); + src->need_flush = FALSE; + return GST_BUFFER (event); + } + /* check for flush */ + if (src->need_flush) { + src->need_flush = FALSE; + GST_DEBUG ("filesrc sending flush"); + return GST_BUFFER (gst_event_new_flush ()); + } + + /* check for EOF */ + if (src->curoffset == src->filelen) { + GST_DEBUG ("filesrc eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT, + src->curoffset, src->filelen); + gst_element_set_eos (GST_ELEMENT (src)); + return GST_BUFFER (gst_event_new (GST_EVENT_EOS)); + } + + if (src->using_mmap){ + return gst_filesrc_get_mmap (src); + }else{ + return gst_filesrc_get_read (src); + } +} + /* open the file and mmap it, necessary to go to READY state */ static gboolean gst_filesrc_open_file (GstFileSrc *src) @@ -677,13 +719,15 @@ gst_filesrc_open_file (GstFileSrc *src) } /* find the file length */ - src->filelen = lseek (src->fd, 0, SEEK_END); - lseek (src->fd, 0, SEEK_SET); + src->filelen = stat_results.st_size; /* allocate the first mmap'd region */ src->mapbuf = gst_filesrc_map_region (src, 0, src->mapsize); - if (src->mapbuf == NULL) - return FALSE; + if (src->mapbuf == NULL) { + src->using_mmap = FALSE; + }else{ + src->using_mmap = TRUE; + } src->curoffset = 0; diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 23715a3..066da9e 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -402,7 +402,7 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size) return NULL; } else if (mmapregion == MAP_FAILED) { - gst_element_error (GST_ELEMENT (src), "mmap (0x%x, %d, 0x%llx) : %s", + GST_DEBUG ("mmap (0x%x, %d, 0x%llx) : %s", size, src->fd, offset, strerror (errno)); return NULL; } @@ -486,50 +486,20 @@ gst_filesrc_search_region_match (gpointer a, gpointer b) } /** - * gst_filesrc_get: + * gst_filesrc_get_mmap: * @pad: #GstPad to push a buffer from * * Push a new buffer from the filesrc at the current offset. */ static GstBuffer * -gst_filesrc_get (GstPad *pad) +gst_filesrc_get_mmap (GstFileSrc *src) { - GstFileSrc *src; GstBuffer *buf = NULL, *map; size_t readsize, mapsize; off_t readend,mapstart,mapend; GstFileSrcRegion region; int i; - g_return_val_if_fail (pad != NULL, NULL); - src = GST_FILESRC (gst_pad_get_parent (pad)); - g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL); - - /* check for seek */ - if (src->seek_happened) { - GstEvent *event; - - src->seek_happened = FALSE; - GST_DEBUG ("filesrc sending discont"); - event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL); - src->need_flush = FALSE; - return GST_BUFFER (event); - } - /* check for flush */ - if (src->need_flush) { - src->need_flush = FALSE; - GST_DEBUG ("filesrc sending flush"); - return GST_BUFFER (gst_event_new_flush ()); - } - - /* check for EOF */ - if (src->curoffset == src->filelen) { - GST_DEBUG ("filesrc eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT, - src->curoffset, src->filelen); - gst_element_set_eos (GST_ELEMENT (src)); - return GST_BUFFER (gst_event_new (GST_EVENT_EOS)); - } - /* 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 */ @@ -649,6 +619,78 @@ gst_filesrc_get (GstPad *pad) return buf; } +static GstBuffer * +gst_filesrc_get_read (GstFileSrc *src) +{ + GstBuffer *buf = NULL; + size_t readsize; + int ret; + + readsize = src->block_size; + if (src->curoffset + readsize > src->filelen) { + readsize = src->filelen - src->curoffset; + } + + buf = gst_buffer_new_and_alloc (readsize); + g_return_val_if_fail (buf != NULL, NULL); + + ret = read (src->fd, GST_BUFFER_DATA (buf), readsize); + if (ret < 0){ + gst_element_error (GST_ELEMENT (src), "reading file (%s)", + strerror (errno), NULL); + return NULL; + } + if (ret < readsize) { + gst_element_error (GST_ELEMENT (src), "unexpected end of file", NULL); + return NULL; + } + + src->curoffset += readsize; + + return buf; +} + +static GstBuffer * +gst_filesrc_get (GstPad *pad) +{ + GstFileSrc *src; + + g_return_val_if_fail (pad != NULL, NULL); + src = GST_FILESRC (gst_pad_get_parent (pad)); + g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL); + + /* check for seek */ + if (src->seek_happened) { + GstEvent *event; + + src->seek_happened = FALSE; + GST_DEBUG ("filesrc sending discont"); + event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL); + src->need_flush = FALSE; + return GST_BUFFER (event); + } + /* check for flush */ + if (src->need_flush) { + src->need_flush = FALSE; + GST_DEBUG ("filesrc sending flush"); + return GST_BUFFER (gst_event_new_flush ()); + } + + /* check for EOF */ + if (src->curoffset == src->filelen) { + GST_DEBUG ("filesrc eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT, + src->curoffset, src->filelen); + gst_element_set_eos (GST_ELEMENT (src)); + return GST_BUFFER (gst_event_new (GST_EVENT_EOS)); + } + + if (src->using_mmap){ + return gst_filesrc_get_mmap (src); + }else{ + return gst_filesrc_get_read (src); + } +} + /* open the file and mmap it, necessary to go to READY state */ static gboolean gst_filesrc_open_file (GstFileSrc *src) @@ -677,13 +719,15 @@ gst_filesrc_open_file (GstFileSrc *src) } /* find the file length */ - src->filelen = lseek (src->fd, 0, SEEK_END); - lseek (src->fd, 0, SEEK_SET); + src->filelen = stat_results.st_size; /* allocate the first mmap'd region */ src->mapbuf = gst_filesrc_map_region (src, 0, src->mapsize); - if (src->mapbuf == NULL) - return FALSE; + if (src->mapbuf == NULL) { + src->using_mmap = FALSE; + }else{ + src->using_mmap = TRUE; + } src->curoffset = 0; -- 2.7.4