gstfilesrc源文件.doc_第1页
gstfilesrc源文件.doc_第2页
gstfilesrc源文件.doc_第3页
gstfilesrc源文件.doc_第4页
gstfilesrc源文件.doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen * 2000,2005 Wim Taymans * * gstfilesrc.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */* * SECTION:element-filesrc * see_also: #GstFileSrc * * Read data from a file in the local file system. */#ifdef HAVE_CONFIG_H# include config.h#endif#include #include gstfilesrc.h#include #include #ifdef G_OS_WIN32#include /* lseek, open, close, read */* On win32, stat* default to 32 bit; we need the 64-bit * variants, so explicitly define it that way. */#define stat _stat64#define fstat _fstat64#undef lseek#define lseek _lseeki64#undef off_t#define off_t guint64/* Prevent stat.h from defining the stat* functions as * _stat*, since were explicitly overriding that */#undef _INC_STAT_INL#endif#include #include #ifdef HAVE_UNISTD_H# include #endif#ifdef HAVE_MMAP# include #endif#include #include #include ././gst/gst-i18n-lib.hstatic GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE (src, GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);/* FIXME we should be using glib for this */#ifndef S_ISREG#define S_ISREG(mode) (mode)&_S_IFREG)#endif#ifndef S_ISDIR#define S_ISDIR(mode) (mode)&_S_IFDIR)#endif#ifndef S_ISSOCK#define S_ISSOCK(x) (0)#endif#ifndef O_BINARY#define O_BINARY (0)#endif/* Copy of glibs g_open due to win32 libc/cross-DLL brokenness: we cant * use the file descriptor opened in glib (and returned from this function) * in this library, as they may have unrelated C runtimes. */intgst_open (const gchar * filename, int flags, int mode)#ifdef G_OS_WIN32 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); int retval; int save_errno; if (wfilename = NULL) errno = EINVAL; return -1; retval = _wopen (wfilename, flags, mode); save_errno = errno; g_free (wfilename); errno = save_errno; return retval;#else return open (filename, flags, mode);#endif/* * GStreamer Default File Source * Theory of Operation * * Update: see GstFileSrc:use-mmap property documentation below * for why use of mmap() is disabled by default. * * This source uses mmap(2) to efficiently load data from a file. * To do this without seriously polluting the applications memory * space, it must do so in smaller chunks, say 1-4MB at a time. * Buffers are then subdivided from these mmapd chunks, to directly * make use of the mmap. * * To handle refcounting so that the mmap can be freed at the appropriate * time, a buffer will be created for each mmapd region, and all new * buffers will be sub-buffers of this top-level buffer. As they are * freed, the refcount goes down on the mmapd buffer and its free() * function is called, which will call munmap(2) on itself. * * If a buffer happens to cross the boundaries of an mmapd region, we * have to decide whether its more efficient to copy the data into a * new buffer, or mmap() just that buffer. There will have to be a * breakpoint size to determine which will be done. The mmap() size * has a lot to do with this as well, because you end up in double- * jeopardy: the larger the outgoing buffer, the more data to copy when * it overlaps, *and* the more frequently youll have buffers that *do* * overlap. * * Seeking is another tricky aspect to do efficiently. The initial * implementation of this source wont make use of these features, however. * The issue is that if an application seeks backwards in a file, *and* * that region of the file is covered by an mmap that hasnt been fully * deallocated, we really should re-use it. But keeping track of these * regions is tricky because we have to lock the structure that holds * them. We need to settle on a locking primitive (GMutex seems to be * a really good option.), then we can do that. */GST_DEBUG_CATEGORY_STATIC (gst_file_src_debug);#define GST_CAT_DEFAULT gst_file_src_debug/* FileSrc signals and args */enum /* FILL ME */ LAST_SIGNAL;#define DEFAULT_BLOCKSIZE 4*1024#define DEFAULT_MMAPSIZE 4*1024*1024#define DEFAULT_TOUCH TRUE#define DEFAULT_USEMMAP FALSE#define DEFAULT_SEQUENTIAL FALSEenum ARG_0, ARG_LOCATION, ARG_FD, ARG_MMAPSIZE, ARG_SEQUENTIAL, ARG_TOUCH, ARG_USEMMAP;static void gst_file_src_finalize (GObject * object);/设置属性的虚函数static void gst_file_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);/获取属性的虚函数static void gst_file_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);static gboolean gst_file_src_start (GstBaseSrc * basesrc);static gboolean gst_file_src_stop (GstBaseSrc * basesrc);static gboolean gst_file_src_is_seekable (GstBaseSrc * src);static gboolean gst_file_src_get_size (GstBaseSrc * src, guint64 * size);static GstFlowReturn gst_file_src_create (GstBaseSrc * src, guint64 offset, guint length, GstBuffer * buffer);static gboolean gst_file_src_query (GstBaseSrc * src, GstQuery * query);static void gst_file_src_uri_handler_init (gpointer g_iface, gpointer iface_data);static void_do_init (GType filesrc_type) static const GInterfaceInfo urihandler_info = gst_file_src_uri_handler_init, NULL, NULL ; g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER, &urihandler_info); GST_DEBUG_CATEGORY_INIT (gst_file_src_debug, filesrc, 0, filesrc element);GST_BOILERPLATE_FULL (GstFileSrc, gst_file_src, GstBaseSrc, GST_TYPE_BASE_SRC, _do_init);/初始化类结构,定义父类,定义类成员(子类),类详细信息。/元件细节在_base_init ()函数中被注册到插件中/:_base_init()用来在创建每个新的子类时,初始化类和子类的属性static voidgst_file_src_base_init (gpointer g_class) GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); gst_element_class_set_details_simple (gstelement_class, File Source, Source/File, Read from arbitrary point in a file, Erik Walthinsen ); /将pad模板注册到element中 gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate);/定义类成员变量:1、定义信号及其响应函数;2、定义虚函数等等。/_class_init()用来对类进行初始化(指定类的信号,参数和虚函数,设定全局状态),该初始化过程只进行一次static voidgst_file_src_class_init (GstFileSrcClass * klass) GObjectClass *gobject_class; GstBaseSrcClass *gstbasesrc_class; gobject_class = G_OBJECT_CLASS (klass); gstbasesrc_class = GST_BASE_SRC_CLASS (klass); gobject_class-set_property = gst_file_src_set_property; gobject_class-get_property = gst_file_src_get_property; g_object_class_install_property (gobject_class, ARG_FD, g_param_spec_int (fd, File-descriptor, File-descriptor for the file being mmap()d, 0, G_MAXINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, ARG_LOCATION, g_param_spec_string (location, File Location, Location of the file to read, NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY); g_object_class_install_property (gobject_class, ARG_MMAPSIZE, g_param_spec_ulong (mmapsize, mmap() Block Size, Size in bytes of mmap()d regions, 0, G_MAXULONG, DEFAULT_MMAPSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING); g_object_class_install_property (gobject_class, ARG_TOUCH, g_param_spec_boolean (touch, Touch mapped region read data, Touch mmapped data regions to force them to be read from disk, DEFAULT_TOUCH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING); /* * GstFileSrc:use-mmap * * Whether to use mmap(). Set to TRUE to force use of mmap() instead of * read() for reading data. * * Use of mmap() is disabled by default since with mmap() there are a * number of occasions where the process/application will be notified of * read errors via a SIGBUS signal from the kernel, which will lead to * the application being killed if not handled by the application. This * is something that is difficult to work around for a library like * GStreamer, hence use of mmap() is disabled by default. Said errors * can occur for example when an external device (e.g. an external hard * drive or a portable music player) are unplugged while in use, or when * a CD/DVD medium cannot be be read because the medium is scratched or * otherwise damaged. * */ g_object_class_install_property (gobject_class, ARG_USEMMAP, g_param_spec_boolean (use-mmap, Use mmap to read data, Whether to use mmap() instead of read(), DEFAULT_USEMMAP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY); g_object_class_install_property (gobject_class, ARG_SEQUENTIAL, g_param_spec_boolean (sequential, Optimise for sequential mmap access, Whether to use madvise to hint to the kernel that access to mmap pages will be sequential, DEFAULT_SEQUENTIAL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING); gobject_class-finalize = GST_DEBUG_FUNCPTR (gst_file_src_finalize); gstbasesrc_class-start = GST_DEBUG_FUNCPTR (gst_file_src_start); gstbasesrc_class-stop = GST_DEBUG_FUNCPTR (gst_file_src_stop); gstbasesrc_class-is_seekable = GST_DEBUG_FUNCPTR (gst_file_src_is_seekable); gstbasesrc_class-get_size = GST_DEBUG_FUNCPTR (gst_file_src_get_size); gstbasesrc_class-create = GST_DEBUG_FUNCPTR (gst_file_src_create); gstbasesrc_class-query = GST_DEBUG_FUNCPTR (gst_file_src_query); if (sizeof (off_t) pagesize = getpagesize ();#endif src-filename = NULL; src-fd = 0; src-uri = NULL; src-touch = DEFAULT_TOUCH; src-mapbuf = NULL; src-mapsize = DEFAULT_MMAPSIZE; /* default is 4MB */ src-use_mmap = DEFAULT_USEMMAP; src-sequential = DEFAULT_SEQUENTIAL; src-is_regular = FALSE;static voidgst_file_src_finalize (GObject * object) GstFileSrc *src; src = GST_FILE_SRC (object); g_free (src-filename); g_free (src-uri); G_OBJECT_CLASS (parent_class)-finalize (object);static gbooleangst_file_src_set_location (GstFileSrc * src, const gchar * location) GstState state; /* the element must be stopped in order to do this */ GST_OBJECT_LOCK (src); state = GST_STATE (src); if (state != GST_STATE_READY & state != GST_STATE_NULL) goto wrong_state; GST_OBJECT_UNLOCK (src); g_free (src-filename); g_free (src-uri); /* clear the filename if we get a NULL (is that possible?) */ if (location = NULL) src-filename = NULL; src-uri = NULL; else /* we store the filename as received by the application. On Windoes this * should be UTF8 */ src-filename = g_strdup (location); src-uri = gst_uri_construct (file, src-filename); g_object_notify (G_OBJECT (src), location); gst_uri_handler_new_uri (GST_URI_HANDLER (src), src-uri); return TRUE; /* ERROR */wrong_state: GST_DEBUG_OBJECT (src, setting location in wrong state); GST_OBJECT_UNLOCK (src); return FALSE; /设置属性static voidgst_file_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) GstFileSrc *src; g_return_if_fail (GST_IS_FILE_SRC (object); src = GST_FILE_SRC (object); switch (prop_id) case ARG_LOCATION: gst_file_src_set_location (src, g_value_get_string (value); break; case ARG_MMAPSIZE: if (src-mapsize % src-pagesize) = 0) src-mapsize = g_value_get_ulong (value); else GST_INFO_OBJECT (src, invalid mapsize, must be a multiple of pagesize, which is %d, src-pagesize); break; case ARG_TOUCH: src-touch = g_value_get_boolean (value); break; case ARG_SEQUENTIAL: src-sequential = g_value_get_boolean (value); break; case ARG_USEMMAP: src-use_mmap = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; /获取属性static voidgst_file_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) GstFileSrc *src; g_return_if_fail (GST_IS_FILE_SRC (object); src = GST_FILE_SRC (object); switch (prop_id) case ARG_LOCATION: g_value_set_string (value, src-filename); break; case ARG_FD: g_value_set_int (value, src-fd); break; case ARG_MMAPSIZE: g_value_set_ulong (value, src-mapsize); break; case ARG_TOUCH: g_value_set_boolean (value, src-touch); break; case ARG_SEQUENTIAL: g_value_set_boolean (value, src-sequential); break; case ARG_USEMMAP: g_value_set_boolean (value, src-use_mmap); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; /* * mmap code below */#ifdef HAVE_MMAP/* GstMmapBuffer */typedef struct _GstMmapBuffer GstMmapBuffer;typedef struct _GstMmapBufferClass GstMmapBufferClass;#define GST_TYPE_MMAP_BUFFER (gst_mmap_buffer_get_type()#define GST_IS_MMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj), GST_TYPE_MMAP_BUFFER)#define GST_IS_MMAP_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE (klass), GST_TYPE_MMAP_BUFFER)#define GST_MMAP_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS (obj), GST_TYPE_MMAP_BUFFER, GstMmapBufferClass)#define GST_MMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj), GST_TYPE_MMAP_BUFFER, GstMmapBuffer)#define GST_MMAP_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass), GST_TYPE_MMAP_BUFFER, GstMmapBufferClass)struct _GstMmapBuffer GstBuffer buffer; GstFileSrc *filesrc;struct _GstMmapBufferClass GstBufferClass buffer_class;static void gst_mmap_buffer_init (GTypeInstance * instance, gpointer g_class);static void gst_mmap_buffer_class_init (gpointer g_class, gpointer class_data);static void gst_mmap_buffer_finalize (GstMmapBuffer * mmap_buffer);static GstBufferClass *mmap_buffer_parent_class = NULL;static GTypegst_mmap_buffer_get_type (void) static GType _gst_mmap_buffer_type; if (G_UNLIKELY (_gst_mmap_buffer_type = 0) static const GTypeInfo mmap_buffer_info = sizeof (GstMmapBufferClass), NULL, NULL, gst_mmap_buffer_class_init, NULL, NULL, sizeof (GstMmapBuffer), 0, gst_mmap_buffer_init, NULL ; _gst_mmap_buffer_type = g_type_register_static (GST_TYPE_BUFFER, GstMmapBuffer, &mmap_buffer_info, 0); return _gst_mmap_buffer_type;static voidgst_mmap_buffer_class_init (gpointer g_class, gpointer class_data) GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); mmap_buffer_parent_class = g_type_class_peek_parent (g_class); mini_object_class-finalize = (GstMiniObjectFinalizeFunction) gst_mmap_buffer_finalize;static voidgst_mmap_buffer_init (GTypeInstance * instance, gpointer g_class) GstBuffer *buf = (GstBuffer *) instance; GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY); /* before we re-enable this flag, we probably need to fix _copy() * _make_writable(), etc. in GstMiniObject/GstBuffer as well */ /* GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_ORIGINAL); */static voidgst_mmap_buffer_finalize (GstMmapBuffer * mmap_buffer) guint size; gpointer data; guint64 offset; GstFileSrc *src; GstBuffer *buffer = GST_BUFFER (mmap_buffer); /* get info */ size = GST_BUFFER_SIZE (buffer); offset = GST_BUFFER_OFFSET (buffer); data = GST_BUFFER_DATA (buffer); src = mmap_buffer-filesrc; GST_LOG (freeing mmap()d buf

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论