static GstFlowReturn gst_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) { GstFileSrc *src; GstFlowReturn ret; src = GST_FILE_SRC_CAST (basesrc); #ifdef HAVE_MMAP if (src->using_mmap) { ret = gst_file_src_create_mmap (src, offset, length, buffer); } else { ret = gst_file_src_create_read (src, offset, length, buffer); } #else ret = gst_file_src_create_read (src, offset, length, buffer); #endif return ret; }
/*** * read code below * that is to say, you shouldn't read the code below, but the code that reads * stuff is below. Well, you shouldn't not read the code below, feel free * to read it of course. It's just that "read code below" is a pretty crappy * documentation string because it sounds like we're expecting you to read * the code to understand what it does, which, while true, is really not * the sort of attitude we want to be advertising. No sir. * */ static GstFlowReturn gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer * buf) { GstFileSrc *src; guint to_read, bytes_read; int ret; GstMapInfo info; guint8 *data; src = GST_FILE_SRC_CAST (basesrc); if (G_UNLIKELY (offset != -1 && src->read_position != offset)) { off_t res; res = lseek (src->fd, offset, SEEK_SET); if (G_UNLIKELY (res < 0 || res != offset)) goto seek_failed; src->read_position = offset; } gst_buffer_map (buf, &info, GST_MAP_WRITE); data = info.data; bytes_read = 0; to_read = length; while (to_read > 0) { GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x", to_read, offset + bytes_read); errno = 0; ret = read (src->fd, data + bytes_read, to_read); if (G_UNLIKELY (ret < 0)) { if (errno == EAGAIN || errno == EINTR) continue; goto could_not_read; } /* files should eos if they read 0 and more was requested */ if (G_UNLIKELY (ret == 0)) { /* .. but first we should return any remaining data */ if (bytes_read > 0) break; goto eos; } to_read -= ret; bytes_read += ret; src->read_position += ret; } gst_buffer_unmap (buf, &info); if (bytes_read != length) gst_buffer_resize (buf, 0, bytes_read); GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET_END (buf) = offset + bytes_read; return GST_FLOW_OK; /* ERROR */ seek_failed: { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); return GST_FLOW_ERROR; } could_not_read: { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); gst_buffer_unmap (buf, &info); gst_buffer_resize (buf, 0, 0); return GST_FLOW_ERROR; } eos: { GST_DEBUG ("EOS"); gst_buffer_unmap (buf, &info); gst_buffer_resize (buf, 0, 0); return GST_FLOW_EOS; } }