gboolean gst_gl_base_buffer_copy_buffer_sub_data (GstGLBaseBuffer * src, GstGLBaseBuffer * dest, gssize offset, gssize size) { const GstGLFuncs *gl = src->context->gl_vtable; GstMapInfo sinfo, dinfo; if (!gl->CopyBufferSubData) /* This is GL(ES) 3.0+ only */ return FALSE; if (!gst_memory_map ((GstMemory *) src, &sinfo, GST_MAP_READ | GST_MAP_GL)) { GST_CAT_WARNING (GST_CAT_GL_BASE_BUFFER, "failed to read map source memory %p", src); return FALSE; } if (!gst_memory_map ((GstMemory *) dest, &dinfo, GST_MAP_WRITE | GST_MAP_GL)) { GST_CAT_WARNING (GST_CAT_GL_BASE_BUFFER, "failed to write map destination memory %p", dest); gst_memory_unmap ((GstMemory *) src, &sinfo); return FALSE; } gl->BindBuffer (GL_COPY_READ_BUFFER, src->id); gl->BindBuffer (GL_COPY_WRITE_BUFFER, dest->id); gl->CopyBufferSubData (GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size); gst_memory_unmap ((GstMemory *) src, &sinfo); gst_memory_unmap ((GstMemory *) dest, &dinfo); return TRUE; }
gboolean gst_gl_base_buffer_memcpy (GstGLBaseBuffer * src, GstGLBaseBuffer * dest, gssize offset, gssize size) { GstMapInfo sinfo, dinfo; if (!gst_memory_map ((GstMemory *) src, &sinfo, GST_MAP_READ)) { GST_CAT_WARNING (GST_CAT_GL_BASE_BUFFER, "could not read map source memory %p", src); return FALSE; } if (!gst_memory_map ((GstMemory *) dest, &dinfo, GST_MAP_WRITE)) { GST_CAT_WARNING (GST_CAT_GL_BASE_BUFFER, "could not write map dest memory %p", dest); gst_memory_unmap ((GstMemory *) src, &sinfo); return FALSE; } GST_CAT_DEBUG (GST_CAT_GL_BASE_BUFFER, "memcpy %" G_GSSIZE_FORMAT " memory %p -> %p", size, src, dest); memcpy (dinfo.data, sinfo.data + offset, size); gst_memory_unmap ((GstMemory *) dest, &dinfo); gst_memory_unmap ((GstMemory *) src, &sinfo); return TRUE; }
/** * gst_gl_base_memory_memcpy: * @src: the source #GstGLBaseMemory * @dest: the destination #GstGLBaseMemory * @offset: the offset to start at * @size: the number of bytes to copy * * Returns: whether the copy suceeded. */ gboolean gst_gl_base_memory_memcpy (GstGLBaseMemory * src, GstGLBaseMemory * dest, gssize offset, gssize size) { GstMapInfo sinfo, dinfo; if (!gst_gl_base_memory_alloc_data (GST_GL_BASE_MEMORY_CAST (dest))) return FALSE; if (!gst_memory_map ((GstMemory *) src, &sinfo, GST_MAP_READ)) { GST_CAT_WARNING (GST_CAT_GL_BASE_MEMORY, "could not read map source memory %p", src); return FALSE; } if (!gst_memory_map ((GstMemory *) dest, &dinfo, GST_MAP_WRITE)) { GST_CAT_WARNING (GST_CAT_GL_BASE_MEMORY, "could not write map dest memory %p", dest); gst_memory_unmap ((GstMemory *) src, &sinfo); return FALSE; } if (size == -1) size = sinfo.size > offset ? sinfo.size - offset : 0; GST_CAT_DEBUG (GST_CAT_GL_BASE_MEMORY, "memcpy %" G_GSSIZE_FORMAT " memory %p -> %p", size, src, dest); memcpy (dinfo.data, sinfo.data + offset, size); gst_memory_unmap ((GstMemory *) dest, &dinfo); gst_memory_unmap ((GstMemory *) src, &sinfo); return TRUE; }
static GstGLBuffer * _gl_buffer_copy (GstGLBuffer * src, gssize offset, gssize size) { GstAllocator *allocator = src->mem.mem.allocator; GstAllocationParams params = { 0, src->mem.mem.align, 0, 0 }; GstGLBuffer *dest = NULL; dest = _gl_buffer_new (allocator, NULL, src->mem.context, src->target, src->usage_hints, ¶ms, src->mem.mem.maxsize); /* If not doing a full copy, then copy to sysmem, the 2D represention of the * texture would become wrong */ if (GST_MEMORY_FLAG_IS_SET (src, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)) { if (!gst_gl_base_memory_memcpy (GST_GL_BASE_MEMORY_CAST (src), GST_GL_BASE_MEMORY_CAST (dest), offset, size)) { GST_CAT_WARNING (GST_CAT_GL_BUFFER, "Could not copy GL Buffer"); gst_memory_unref (GST_MEMORY_CAST (dest)); dest = NULL; } } else { if (!gst_gl_buffer_copy_buffer_sub_data (src, dest, offset, size)) { if (!gst_gl_base_memory_memcpy (GST_GL_BASE_MEMORY_CAST (src), GST_GL_BASE_MEMORY_CAST (dest), offset, size)) { GST_CAT_WARNING (GST_CAT_GL_BUFFER, "Could not copy GL Buffer"); gst_memory_unref (GST_MEMORY_CAST (dest)); dest = NULL; } } } return dest; }
static GstMemory * _gl_mem_copy (GstGLMemoryPBO * src, gssize offset, gssize size) { GstAllocationParams params = { 0, GST_MEMORY_CAST (src)->align, 0, 0 }; GstGLBaseMemoryAllocator *base_mem_allocator; GstAllocator *allocator; GstMemory *dest = NULL; allocator = GST_MEMORY_CAST (src)->allocator; base_mem_allocator = (GstGLBaseMemoryAllocator *) allocator; if (src->mem.tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) { GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Cannot copy External OES textures"); return NULL; } /* If not doing a full copy, then copy to sysmem, the 2D represention of the * texture would become wrong */ if (offset > 0 || size < GST_MEMORY_CAST (src)->size) { return base_mem_allocator->fallback_mem_copy (GST_MEMORY_CAST (src), offset, size); } dest = (GstMemory *) _gl_mem_new (allocator, NULL, src->mem.mem.context, src->mem.tex_target, ¶ms, &src->mem.info, src->mem.plane, &src->mem.valign, NULL, NULL); if (GST_MEMORY_FLAG_IS_SET (src, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)) { if (!gst_gl_base_memory_memcpy ((GstGLBaseMemory *) src, (GstGLBaseMemory *) dest, offset, size)) { GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Could not copy GL Memory"); gst_memory_unref (GST_MEMORY_CAST (dest)); return NULL; } } else { GstMapInfo dinfo; if (!gst_memory_map (GST_MEMORY_CAST (dest), &dinfo, GST_MAP_WRITE | GST_MAP_GL)) { GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Failed not map destination " "for writing"); gst_memory_unref (GST_MEMORY_CAST (dest)); return NULL; } if (!gst_gl_memory_copy_into ((GstGLMemory *) src, ((GstGLMemory *) dest)->tex_id, src->mem.tex_target, src->mem.tex_type, src->mem.tex_width, GL_MEM_HEIGHT (src))) { GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Could not copy GL Memory"); gst_memory_unmap (GST_MEMORY_CAST (dest), &dinfo); gst_memory_unref (GST_MEMORY_CAST (dest)); return NULL; } gst_memory_unmap (GST_MEMORY_CAST (dest), &dinfo); } return dest; }
static VkBool32 _gst_vk_debug_callback (VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, void *pUserData) { if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { GST_CAT_ERROR (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { GST_CAT_WARNING (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { GST_CAT_LOG (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { GST_CAT_FIXME (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { GST_CAT_TRACE (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); } else { return FALSE; } /* * false indicates that layer should not bail-out of an * API call that had validation failures. This may mean that the * app dies inside the driver due to invalid parameter(s). * That's what would happen without validation layers, so we'll * keep that behavior here. */ return FALSE; }
/** * gst_buffer_try_new_and_alloc: * @size: the size of the new buffer's data. * * Tries to create a newly allocated buffer with data of the given size. If * the requested amount of memory can't be allocated, NULL will be returned. * The buffer memory is not cleared. * * Note that when @size == 0, the buffer data pointer will be NULL. * * MT safe. * * Returns: a new #GstBuffer, or NULL if the memory couldn't be allocated. * * Since: 0.10.13 */ GstBuffer * gst_buffer_try_new_and_alloc (guint size) { GstBuffer *newbuf; guint8 *malloc_data; malloc_data = g_try_malloc (size); if (G_UNLIKELY (malloc_data == NULL && size != 0)) { GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size); return NULL; } /* FIXME: there's no g_type_try_create_instance() in GObject yet, so this * will still abort if a new GstBuffer structure can't be allocated */ newbuf = gst_buffer_new (); GST_BUFFER_MALLOCDATA (newbuf) = malloc_data; GST_BUFFER_DATA (newbuf) = malloc_data; GST_BUFFER_SIZE (newbuf) = size; GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size); return newbuf; }
static GstMemory * _fallback_mem_copy (GstMemory * mem, gssize offset, gssize size) { GstMemory *copy; GstMapInfo sinfo, dinfo; GstAllocationParams params = { 0, mem->align, 0, 0, }; GstAllocator *allocator; if (!gst_memory_map (mem, &sinfo, GST_MAP_READ)) return NULL; if (size == -1) size = sinfo.size > offset ? sinfo.size - offset : 0; /* use the same allocator as the memory we copy */ allocator = mem->allocator; if (GST_OBJECT_FLAG_IS_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC)) allocator = NULL; copy = gst_allocator_alloc (allocator, size, ¶ms); if (!gst_memory_map (copy, &dinfo, GST_MAP_WRITE)) { GST_CAT_WARNING (GST_CAT_MEMORY, "could not write map memory %p", copy); gst_allocator_free (mem->allocator, copy); gst_memory_unmap (mem, &sinfo); return NULL; } GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "memcpy %" G_GSSIZE_FORMAT " memory %p -> %p", size, mem, copy); memcpy (dinfo.data, sinfo.data + offset, size); gst_memory_unmap (copy, &dinfo); gst_memory_unmap (mem, &sinfo); return copy; }
/** * gst_buffer_try_new_and_alloc: * @size: the size of the new buffer's data. * * Tries to create a newly allocated buffer with data of the given size. If * the requested amount of memory can't be allocated, NULL will be returned. * The buffer memory is not cleared. * * Note that when @size == 0, the buffer data pointer will be NULL. * * MT safe. * * Returns: a new #GstBuffer, or NULL if the memory couldn't be allocated. * * Since: 0.10.13 */ GstBuffer * gst_buffer_try_new_and_alloc (guint size) { GstBuffer *newbuf; guint8 *malloc_data; #ifdef HAVE_POSIX_MEMALIGN gpointer memptr = NULL; if (G_LIKELY (size)) { if (G_UNLIKELY (!aligned_malloc (&memptr, size))) { GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size); return NULL; } } malloc_data = (guint8 *) memptr; #else malloc_data = g_try_malloc (size); if (G_UNLIKELY (malloc_data == NULL && size != 0)) { GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size); return NULL; } #endif /* FIXME: there's no g_type_try_create_instance() in GObject yet, so this * will still abort if a new GstBuffer structure can't be allocated */ newbuf = gst_buffer_new (); GST_BUFFER_MALLOCDATA (newbuf) = malloc_data; GST_BUFFER_DATA (newbuf) = malloc_data; GST_BUFFER_SIZE (newbuf) = size; #ifdef HAVE_POSIX_MEMALIGN GST_BUFFER_FREE_FUNC (newbuf) = free; #endif GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size); return newbuf; }
static gboolean ensure_data (GstVdpVideoMemory * vmem) { VdpStatus vdp_stat; GstVideoInfo *info = vmem->info; #ifndef GST_DISABLE_GST_DEBUG GstClockTime before, after; #endif if (g_atomic_int_add (&vmem->refcount, 1) > 1) return TRUE; /* Allocate enough room to store data */ vmem->cache = g_malloc (GST_VIDEO_INFO_SIZE (info)); vmem->cached_data[0] = vmem->cache; vmem->cached_data[1] = vmem->cache + GST_VIDEO_INFO_PLANE_OFFSET (info, 1); vmem->cached_data[2] = vmem->cache + GST_VIDEO_INFO_PLANE_OFFSET (info, 2); vmem->destination_pitches[0] = GST_VIDEO_INFO_PLANE_STRIDE (info, 0); vmem->destination_pitches[1] = GST_VIDEO_INFO_PLANE_STRIDE (info, 1); vmem->destination_pitches[2] = GST_VIDEO_INFO_PLANE_STRIDE (info, 2); GST_DEBUG ("cached_data %p %p %p", vmem->cached_data[0], vmem->cached_data[1], vmem->cached_data[2]); GST_DEBUG ("pitches %d %d %d", vmem->destination_pitches[0], vmem->destination_pitches[1], vmem->destination_pitches[2]); #ifndef GST_DISABLE_GST_DEBUG before = gst_util_get_timestamp (); #endif vdp_stat = vmem->device->vdp_video_surface_get_bits_ycbcr (vmem->surface, vmem->ycbcr_format, vmem->cached_data, vmem->destination_pitches); #ifndef GST_DISABLE_GST_DEBUG after = gst_util_get_timestamp (); #endif GST_CAT_WARNING (GST_CAT_PERFORMANCE, "Downloading took %" GST_TIME_FORMAT, GST_TIME_ARGS (after - before)); if (vdp_stat != VDP_STATUS_OK) { GST_ERROR ("Failed to get bits : %s", vmem->device->vdp_get_error_string (vdp_stat)); g_free (vmem->cache); vmem->cache = NULL; return FALSE; } return TRUE; }
static void _upload_transfer (GstGLContext * context, GstGLMemoryPBO * gl_mem) { GstGLBaseMemory *mem = (GstGLBaseMemory *) gl_mem; GstMapInfo info; g_mutex_lock (&mem->lock); gl_mem->pbo->target = GL_PIXEL_UNPACK_BUFFER; if (!gst_memory_map (GST_MEMORY_CAST (gl_mem->pbo), &info, GST_MAP_READ | GST_MAP_GL)) { GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Failed to map pbo for reading"); } else { gst_memory_unmap (GST_MEMORY_CAST (gl_mem->pbo), &info); } g_mutex_unlock (&mem->lock); }
static gpointer _pbo_download_transfer (GstGLMemoryPBO * gl_mem, GstMapInfo * info, gsize size) { GstMapInfo *pbo_info; gl_mem->pbo->target = GL_PIXEL_PACK_BUFFER; /* texture -> pbo */ if (info->flags & GST_MAP_READ && GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD)) { GstMapInfo info; GST_CAT_TRACE (GST_CAT_GL_MEMORY, "attempting download of texture %u " "using pbo %u", gl_mem->mem.tex_id, gl_mem->pbo->id); if (!gst_memory_map (GST_MEMORY_CAST (gl_mem->pbo), &info, GST_MAP_WRITE | GST_MAP_GL)) { GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Failed to write to PBO"); return NULL; } if (!_read_pixels_to_pbo (gl_mem)) { gst_memory_unmap (GST_MEMORY_CAST (gl_mem->pbo), &info); return NULL; } gst_memory_unmap (GST_MEMORY_CAST (gl_mem->pbo), &info); } pbo_info = g_new0 (GstMapInfo, 1); /* pbo -> data */ /* get a cpu accessible mapping from the pbo */ if (!gst_memory_map (GST_MEMORY_CAST (gl_mem->pbo), pbo_info, info->flags)) { GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Failed to map pbo"); g_free (pbo_info); return NULL; } info->user_data[0] = pbo_info; return pbo_info->data; }
static GList* fs_rtp_dtmf_event_source_class_add_blueprint (FsRtpSpecialSourceClass *klass, GList *blueprints) { GList *item; GList *already_done = NULL; GstElementFactory *fact = NULL; GList *new_blueprints = NULL; fact = gst_element_factory_find ("rtpdtmfsrc"); if (fact) { gst_object_unref (fact); } else { GST_CAT_WARNING (fsrtpconference_disco, "Could not find rtpdtmfsrc, will not offer DTMF events"); return blueprints; } fact = gst_element_factory_find ("rtpdtmfdepay"); if (!fact) GST_CAT_WARNING (fsrtpconference_disco, "Could not find rtpdtmfdepay, will not be able to receive DTMF events"); for (item = g_list_first (blueprints); item; item = g_list_next (item)) { CodecBlueprint *bp = item->data; GList *done_item = NULL; gboolean skip = FALSE; CodecBlueprint *new_bp = NULL; if (bp->codec->media_type != FS_MEDIA_TYPE_AUDIO) continue; if (!g_ascii_strcasecmp (bp->codec->encoding_name, "telephone-event")) continue; if (bp->codec->clock_rate == 0) continue; for (done_item = g_list_first (already_done); done_item; done_item = g_list_next (done_item)) { if (GPOINTER_TO_UINT (done_item->data) == bp->codec->clock_rate) { skip = TRUE; break; } } if (skip) continue; new_bp = g_slice_new0 (CodecBlueprint); new_bp->codec = fs_codec_new (FS_CODEC_ID_ANY, "telephone-event", FS_MEDIA_TYPE_AUDIO, bp->codec->clock_rate); fs_codec_add_optional_parameter (new_bp->codec, "events", "0-15"); new_bp->rtp_caps = fs_codec_to_gst_caps (new_bp->codec); new_bp->media_caps = gst_caps_new_any (); if (fact) new_bp->receive_pipeline_factory = g_list_prepend (NULL, g_list_prepend (NULL, gst_object_ref (fact))); new_blueprints = g_list_append (new_blueprints, new_bp); already_done = g_list_prepend (already_done, GUINT_TO_POINTER (bp->codec->clock_rate)); } if (fact) gst_object_unref (fact); g_list_free (already_done); blueprints = g_list_concat (blueprints, new_blueprints); return blueprints; }
gint main (gint argc, gchar * argv[]) { gst_init (&argc, &argv); GST_DEBUG_CATEGORY_INIT (cat_default, "GST_Check_default", 0, "default category for this test"); GST_DEBUG_CATEGORY_INIT (cat2, "GST_Check_2", 0, "second category for this test"); #ifndef GST_DISABLE_GST_DEBUG g_assert (gst_debug_remove_log_function (gst_debug_log_default) == 1); #endif gst_debug_add_log_function (check_message, NULL); count = 0; GST_ERROR ("This is an error."); ++count; GST_WARNING ("This is a warning."); ++count; GST_INFO ("This is an info message."); ++count; GST_DEBUG ("This is a debug message."); ++count; GST_LOG ("This is a log message."); ++count; GST_CAT_ERROR (cat2, "This is an error with category."); ++count; GST_CAT_WARNING (cat2, "This is a warning with category."); ++count; GST_CAT_INFO (cat2, "This is an info message with category."); ++count; GST_CAT_DEBUG (cat2, "This is a debug message with category."); ++count; GST_CAT_LOG (cat2, "This is a log message with category."); count = -1; pipeline = gst_element_factory_make ("pipeline", "testelement"); count = 10; GST_ERROR_OBJECT (pipeline, "This is an error with object."); ++count; GST_WARNING_OBJECT (pipeline, "This is a warning with object."); ++count; GST_INFO_OBJECT (pipeline, "This is an info message with object."); ++count; GST_DEBUG_OBJECT (pipeline, "This is a debug message with object."); ++count; GST_LOG_OBJECT (pipeline, "This is a log message with object."); ++count; GST_CAT_ERROR_OBJECT (cat2, pipeline, "This is an error with category and object."); ++count; GST_CAT_WARNING_OBJECT (cat2, pipeline, "This is a warning with category and object."); ++count; GST_CAT_INFO_OBJECT (cat2, pipeline, "This is an info message with category and object."); ++count; GST_CAT_DEBUG_OBJECT (cat2, pipeline, "This is a debug message with category and object."); ++count; GST_CAT_LOG_OBJECT (cat2, pipeline, "This is a log message with category and object."); count = -1; #ifndef GST_DISABLE_GST_DEBUG g_assert (gst_debug_remove_log_function (check_message) == 1); #endif return 0; }
/* we have no fail cases yet, but maybe in the future */ static gboolean init_pre (GOptionContext * context, GOptionGroup * group, gpointer data, GError ** error) { gchar *libdir; if (gst_initialized) { GST_DEBUG ("already initialized"); return TRUE; } _priv_gst_start_time = gst_util_get_timestamp (); #ifndef GST_DISABLE_GST_DEBUG _priv_gst_debug_init (); priv_gst_dump_dot_dir = g_getenv ("GST_DEBUG_DUMP_DOT_DIR"); #endif #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif /* ENABLE_NLS */ /* This is the earliest we can make stuff show up in the logs. * So give some useful info about GStreamer here */ #ifdef G_OS_WIN32 { gchar *basedir = g_win32_get_package_installation_directory_of_module (_priv_gst_dll_handle); libdir = g_build_filename (basedir, #ifdef _DEBUG "debug" #endif "lib", NULL); g_free (basedir); } #else libdir = g_strdup (LIBDIR); #endif GST_INFO ("Initializing GStreamer Core Library version %s", VERSION); GST_INFO ("Using library installed in %s", libdir); g_free (libdir); /* Print some basic system details if possible (OS/architecture) */ #ifdef HAVE_SYS_UTSNAME_H { struct utsname sys_details; if (uname (&sys_details) == 0) { GST_INFO ("%s %s %s %s %s", sys_details.sysname, sys_details.nodename, sys_details.release, sys_details.version, sys_details.machine); } } #endif #ifndef G_ATOMIC_LOCK_FREE GST_CAT_WARNING (GST_CAT_PERFORMANCE, "GLib atomic operations are NOT " "implemented using real hardware atomic operations!"); #endif return TRUE; }
/** * gst_plugin_load_file: * @filename: the plugin filename to load * @error: pointer to a NULL-valued GError * * Loads the given plugin and refs it. Caller needs to unref after use. * * Returns: a reference to the existing loaded GstPlugin, a reference to the * newly-loaded GstPlugin, or NULL if an error occurred. */ GstPlugin * gst_plugin_load_file (const gchar * filename, GError ** error) { GstPlugin *plugin; GModule *module; gboolean ret; gpointer ptr; struct stat file_status; GstRegistry *registry; g_return_val_if_fail (filename != NULL, NULL); registry = gst_registry_get_default (); g_static_mutex_lock (&gst_plugin_loading_mutex); plugin = gst_registry_lookup (registry, filename); if (plugin) { if (plugin->module) { g_static_mutex_unlock (&gst_plugin_loading_mutex); return plugin; } else { gst_object_unref (plugin); plugin = NULL; } } GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"", filename); if (g_module_supported () == FALSE) { GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "module loading not supported"); g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "Dynamic loading not supported"); goto return_error; } if (g_stat (filename, &file_status)) { GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "problem accessing file"); g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "Problem accessing file %s: %s", filename, g_strerror (errno)); goto return_error; } module = g_module_open (filename, G_MODULE_BIND_LOCAL); if (module == NULL) { GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "module_open failed: %s", g_module_error ()); g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "Opening module failed: %s", g_module_error ()); /* If we failed to open the shared object, then it's probably because a * plugin is linked against the wrong libraries. Print out an easy-to-see * message in this case. */ g_warning ("Failed to load plugin '%s': %s", filename, g_module_error ()); goto return_error; } plugin = g_object_new (GST_TYPE_PLUGIN, NULL); plugin->module = module; plugin->filename = g_strdup (filename); plugin->basename = g_path_get_basename (filename); plugin->file_mtime = file_status.st_mtime; plugin->file_size = file_status.st_size; ret = g_module_symbol (module, "gst_plugin_desc", &ptr); if (!ret) { GST_DEBUG ("Could not find plugin entry point in \"%s\"", filename); g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "File \"%s\" is not a GStreamer plugin", filename); g_module_close (module); goto return_error; } plugin->orig_desc = (GstPluginDesc *) ptr; /* check plugin description: complain about bad values but accept them, to * maintain backwards compatibility (FIXME: 0.11) */ CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, name, filename); CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, description, filename); CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, version, filename); CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, license, filename); CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, source, filename); CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, package, filename); CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, origin, filename); GST_LOG ("Plugin %p for file \"%s\" prepared, calling entry function...", plugin, filename); /* this is where we load the actual .so, so let's trap SIGSEGV */ _gst_plugin_fault_handler_setup (); _gst_plugin_fault_handler_filename = plugin->filename; GST_LOG ("Plugin %p for file \"%s\" prepared, registering...", plugin, filename); if (!gst_plugin_register_func (plugin, plugin->orig_desc)) { /* remove signal handler */ _gst_plugin_fault_handler_restore (); GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename); /* plugin == NULL */ g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "File \"%s\" appears to be a GStreamer plugin, but it failed to initialize", filename); g_module_close (module); goto return_error; } /* remove signal handler */ _gst_plugin_fault_handler_restore (); _gst_plugin_fault_handler_filename = NULL; GST_INFO ("plugin \"%s\" loaded", plugin->filename); gst_object_ref (plugin); gst_default_registry_add_plugin (plugin); g_static_mutex_unlock (&gst_plugin_loading_mutex); return plugin; return_error: { if (plugin) gst_object_unref (plugin); g_static_mutex_unlock (&gst_plugin_loading_mutex); return NULL; } }
/* we have no fail cases yet, but maybe in the future */ static gboolean init_pre (GOptionContext * context, GOptionGroup * group, gpointer data, GError ** error) { if (gst_initialized) { GST_DEBUG ("already initialized"); return TRUE; } #if !GLIB_CHECK_VERSION(2, 35, 0) g_type_init (); #endif #ifndef GST_DISABLE_GST_DEBUG _priv_gst_debug_init (); #endif #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif /* ENABLE_NLS */ #ifndef GST_DISABLE_GST_DEBUG { const gchar *debug_list; const gchar *color_mode; if (g_getenv ("GST_DEBUG_NO_COLOR") != NULL) gst_debug_set_color_mode (GST_DEBUG_COLOR_MODE_OFF); color_mode = g_getenv ("GST_DEBUG_COLOR_MODE"); if (color_mode) gst_debug_set_color_mode_from_string (color_mode); debug_list = g_getenv ("GST_DEBUG"); if (debug_list) { gst_debug_set_threshold_from_string (debug_list, FALSE); } } priv_gst_dump_dot_dir = g_getenv ("GST_DEBUG_DUMP_DOT_DIR"); #endif /* This is the earliest we can make stuff show up in the logs. * So give some useful info about GStreamer here */ GST_INFO ("Initializing GStreamer Core Library version %s", VERSION); GST_INFO ("Using library installed in %s", LIBDIR); /* Print some basic system details if possible (OS/architecture) */ #ifdef HAVE_SYS_UTSNAME_H { struct utsname sys_details; if (uname (&sys_details) == 0) { GST_INFO ("%s %s %s %s %s", sys_details.sysname, sys_details.nodename, sys_details.release, sys_details.version, sys_details.machine); } } #endif #ifndef G_ATOMIC_LOCK_FREE GST_CAT_WARNING (GST_CAT_PERFORMANCE, "GLib atomic operations are NOT " "implemented using real hardware atomic operations!"); #endif return TRUE; }