commit cb40a26 Author: Alessandro Decina Date: Fri Jan 03 08:16:54 2014 -0800 Bug 806917 - support GStreamer 1.0 --- configure.in | 66 ++- content/media/gstreamer/GStreamerAllocator.cpp | 198 +++++++ content/media/gstreamer/GStreamerAllocator.h | 25 + content/media/gstreamer/GStreamerFormatHelper.cpp | 13 +- content/media/gstreamer/GStreamerFunctionList.h | 93 +++- content/media/gstreamer/GStreamerLoader.cpp | 48 +- content/media/gstreamer/GStreamerLoader.h | 8 + content/media/gstreamer/GStreamerReader-0.10.cpp | 203 +++++++ content/media/gstreamer/GStreamerReader.cpp | 632 ++++++++++++++-------- content/media/gstreamer/GStreamerReader.h | 42 +- content/media/gstreamer/moz.build | 11 +- content/media/test/manifest.js | 6 +- 12 files changed, 1061 insertions(+), 284 deletions(-) diff --git configure.in configure.in index 9776b8d..0b1698d 100644 --- configure.in +++ configure.in @@ -3955,6 +3955,7 @@ MOZ_SAMPLE_TYPE_FLOAT32= MOZ_SAMPLE_TYPE_S16= MOZ_OPUS=1 MOZ_WEBM=1 +MOZ_GSTREAMER= MOZ_DIRECTSHOW= MOZ_WMF= MOZ_FMP4= @@ -5606,43 +5607,60 @@ dnl = Enable GStreamer dnl ======================================================== if test "$OS_TARGET" = "Linux"; then MOZ_GSTREAMER=1 + GST_API_VERSION=0.10 fi -MOZ_ARG_ENABLE_BOOL(gstreamer, -[ --enable-gstreamer Enable GStreamer support], -MOZ_GSTREAMER=1, -MOZ_GSTREAMER=) - -if test "$MOZ_GSTREAMER"; then - # API version, eg 0.10, 1.0 etc +MOZ_ARG_ENABLE_STRING(gstreamer, +[ --enable-gstreamer[=0.10] Enable GStreamer support], +[ MOZ_GSTREAMER=1 + # API version, eg 0.10, 1.0 etc + if test -z "$enableval" -o "$enableval" = "yes"; then GST_API_VERSION=0.10 + elif test "$enableval" = "no"; then + MOZ_GSTREAMER= + else + GST_API_VERSION=$enableval + fi], +) + +if test -n "$MOZ_GSTREAMER"; then # core/base release number - GST_VERSION=0.10.25 + if test "$GST_API_VERSION" = "1.0"; then + GST_VERSION=1.0 + else + GST_VERSION=0.10.25 + fi + PKG_CHECK_MODULES(GSTREAMER, gstreamer-$GST_API_VERSION >= $GST_VERSION gstreamer-app-$GST_API_VERSION - gstreamer-plugins-base-$GST_API_VERSION, , - AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer])) - if test -n "$GSTREAMER_LIBS"; then - _SAVE_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" - AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=) - if test -n "$_HAVE_LIBGSTVIDEO" ; then - GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" - else - AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.]) - fi - LDFLAGS=$_SAVE_LDFLAGS + gstreamer-plugins-base-$GST_API_VERSION, + [_HAVE_GSTREAMER=1], + [_HAVE_GSTREAMER=]) + if test -z "$_HAVE_GSTREAMER"; then + AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer]) + fi + + _SAVE_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" + AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=) + if test -n "$_HAVE_LIBGSTVIDEO" ; then + GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" else - AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer]) + AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.]) fi + LDFLAGS=$_SAVE_LDFLAGS + + AC_SUBST(GSTREAMER_CFLAGS) + AC_SUBST(GSTREAMER_LIBS) fi -AC_SUBST(GSTREAMER_CFLAGS) -AC_SUBST(GSTREAMER_LIBS) + AC_SUBST(MOZ_GSTREAMER) +AC_SUBST(GST_API_VERSION) if test -n "$MOZ_GSTREAMER"; then - AC_DEFINE(MOZ_GSTREAMER) + AC_DEFINE(MOZ_GSTREAMER) + AC_DEFINE_UNQUOTED(GST_API_VERSION, "$GST_API_VERSION") fi diff --git content/media/gstreamer/GStreamerAllocator.cpp content/media/gstreamer/GStreamerAllocator.cpp new file mode 100644 index 0000000..69d0385 --- /dev/null +++ content/media/gstreamer/GStreamerAllocator.cpp @@ -0,0 +1,198 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "GStreamerAllocator.h" + +#include +#include + +#include "GStreamerLoader.h" + +using namespace mozilla::layers; + +namespace mozilla { + +typedef struct +{ + GstAllocator parent; + GStreamerReader *reader; +} MozGfxMemoryAllocator; + +typedef struct +{ + GstAllocatorClass parent; +} MozGfxMemoryAllocatorClass; + +typedef struct +{ + GstMemory memory; + PlanarYCbCrImage* image; + guint8* data; +} MozGfxMemory; + +typedef struct +{ + GstMeta meta; +} MozGfxMeta; + +typedef struct +{ + GstVideoBufferPoolClass parent_class; +} MozGfxBufferPoolClass; + +typedef struct +{ + GstVideoBufferPool pool; +} MozGfxBufferPool; + +G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR); +G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL); + +void +moz_gfx_memory_reset(MozGfxMemory *mem) +{ + if (mem->image) + mem->image->Release(); + + ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer(); + ImageFormat format = PLANAR_YCBCR; + mem->image = reinterpret_cast(container->CreateImage(&format, 1).get()); + mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size); +} + +static GstMemory* +moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize, + GstAllocationParams* aParams) +{ + MozGfxMemory* mem = g_slice_new (MozGfxMemory); + gsize maxsize = aSize + aParams->prefix + aParams->padding; + gst_memory_init(GST_MEMORY_CAST (mem), + (GstMemoryFlags)aParams->flags, + aAllocator, NULL, maxsize, aParams->align, + aParams->prefix, aSize); + mem->image = NULL; + moz_gfx_memory_reset(mem); + + return (GstMemory *) mem; +} + +static void +moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem) +{ + MozGfxMemory *mem = (MozGfxMemory *) gmem; + + if (mem->memory.parent) + goto sub_mem; + + if (mem->image) + mem->image->Release(); + +sub_mem: + g_slice_free (MozGfxMemory, mem); +} + +static gpointer +moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags) +{ + // check that the allocation didn't fail + if (mem->data == nullptr) + return nullptr; + + return mem->data + mem->memory.offset; +} + +static gboolean +moz_gfx_memory_unmap (MozGfxMemory * mem) +{ + return TRUE; +} + +static MozGfxMemory * +moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size) +{ + MozGfxMemory *sub; + GstMemory *parent; + + /* find the real parent */ + if ((parent = mem->memory.parent) == NULL) + parent = (GstMemory *) mem; + + if (size == (gsize) -1) + size = mem->memory.size - offset; + + /* the shared memory is always readonly */ + sub = g_slice_new (MozGfxMemory); + + gst_memory_init (GST_MEMORY_CAST (sub), + (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY), + mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align, + mem->memory.offset + offset, size); + + sub->image = mem->image; + sub->data = mem->data; + + return sub; +} + +static void +moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass) +{ + GstAllocatorClass *allocator_class; + + allocator_class = (GstAllocatorClass *) klass; + + allocator_class->alloc = moz_gfx_memory_allocator_alloc; + allocator_class->free = moz_gfx_memory_allocator_free; +} + +static void +moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator) +{ + GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); + + alloc->mem_type = "moz-gfx-image"; + alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map; + alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap; + alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share; + /* fallback copy and is_span */ +} + +void +moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader) +{ + MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator; + allocator->reader = aReader; +} + +nsRefPtr +moz_gfx_memory_get_image(GstMemory *aMemory) +{ + NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image"); + + return ((MozGfxMemory *) aMemory)->image; +} + +void +moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer) +{ + GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); + + NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image"); + moz_gfx_memory_reset((MozGfxMemory *) mem); + GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer); +} + +static void +moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass) +{ + GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass; + pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer; +} + +static void +moz_gfx_buffer_pool_init (MozGfxBufferPool * pool) +{ +} + +} // namespace mozilla diff --git content/media/gstreamer/GStreamerAllocator.h content/media/gstreamer/GStreamerAllocator.h new file mode 100644 index 0000000..05a4412 --- /dev/null +++ content/media/gstreamer/GStreamerAllocator.h @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if !defined(GStreamerAllocator_h_) +#define GStreamerAllocator_h_ + +#include "GStreamerReader.h" + +#define GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR (moz_gfx_memory_allocator_get_type()) +#define GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR)) +#define GST_TYPE_MOZ_GFX_BUFFER_POOL (moz_gfx_buffer_pool_get_type()) +#define GST_IS_MOZ_GFX_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_BUFFER_POOL)) + +namespace mozilla { + +GType moz_gfx_memory_allocator_get_type(); +void moz_gfx_memory_allocator_set_reader(GstAllocator *aAllocator, GStreamerReader* aReader); +nsRefPtr moz_gfx_memory_get_image(GstMemory *aMemory); + +GType moz_gfx_buffer_pool_get_type(); + +} // namespace mozilla + +#endif diff --git content/media/gstreamer/GStreamerFormatHelper.cpp content/media/gstreamer/GStreamerFormatHelper.cpp index be71331..a5e5db8 100644 --- content/media/gstreamer/GStreamerFormatHelper.cpp +++ content/media/gstreamer/GStreamerFormatHelper.cpp @@ -294,12 +294,23 @@ bool GStreamerFormatHelper::CanHandleCodecCaps(GstCaps* aCaps) GList* GStreamerFormatHelper::GetFactories() { NS_ASSERTION(sLoadOK, "GStreamer library not linked"); - uint32_t cookie = gst_default_registry_get_feature_list_cookie (); +#if GST_VERSION_MAJOR >= 1 + uint32_t cookie = gst_registry_get_feature_list_cookie(gst_registry_get()); +#else + uint32_t cookie = gst_default_registry_get_feature_list_cookie(); +#endif if (cookie != mCookie) { g_list_free(mFactories); +#if GST_VERSION_MAJOR >= 1 + mFactories = + gst_registry_feature_filter(gst_registry_get(), + (GstPluginFeatureFilter)FactoryFilter, + false, nullptr); +#else mFactories = gst_default_registry_feature_filter((GstPluginFeatureFilter)FactoryFilter, false, nullptr); +#endif mCookie = cookie; } diff --git content/media/gstreamer/GStreamerFunctionList.h content/media/gstreamer/GStreamerFunctionList.h index 56877c0..e169449 100644 --- content/media/gstreamer/GStreamerFunctionList.h +++ content/media/gstreamer/GStreamerFunctionList.h @@ -9,7 +9,6 @@ * List of symbol names we need to dlsym from the gstreamer library. */ GST_FUNC(LIBGSTAPP, gst_app_sink_get_type) -GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer) GST_FUNC(LIBGSTAPP, gst_app_sink_set_callbacks) GST_FUNC(LIBGSTAPP, gst_app_src_end_of_stream) GST_FUNC(LIBGSTAPP, gst_app_src_get_size) @@ -22,10 +21,8 @@ GST_FUNC(LIBGSTAPP, gst_app_src_set_stream_type) GST_FUNC(LIBGSTREAMER, gst_bin_get_by_name) GST_FUNC(LIBGSTREAMER, gst_bin_get_type) GST_FUNC(LIBGSTREAMER, gst_bin_iterate_recurse) -GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata) GST_FUNC(LIBGSTREAMER, gst_buffer_get_type) GST_FUNC(LIBGSTREAMER, gst_buffer_new) -GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc) GST_FUNC(LIBGSTREAMER, gst_bus_set_sync_handler) GST_FUNC(LIBGSTREAMER, gst_bus_timed_pop_filtered) GST_FUNC(LIBGSTREAMER, gst_caps_append) @@ -37,47 +34,37 @@ GST_FUNC(LIBGSTREAMER, gst_caps_new_any) GST_FUNC(LIBGSTREAMER, gst_caps_new_empty) GST_FUNC(LIBGSTREAMER, gst_caps_new_full) GST_FUNC(LIBGSTREAMER, gst_caps_new_simple) -GST_FUNC(LIBGSTREAMER, gst_caps_unref) -GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass) +GST_FUNC(LIBGSTREAMER, gst_caps_set_simple) GST_FUNC(LIBGSTREAMER, gst_element_factory_get_static_pad_templates) GST_FUNC(LIBGSTREAMER, gst_element_factory_get_type) GST_FUNC(LIBGSTREAMER, gst_element_factory_make) GST_FUNC(LIBGSTREAMER, gst_element_get_factory) -GST_FUNC(LIBGSTREAMER, gst_element_get_pad) +GST_FUNC(LIBGSTREAMER, gst_element_get_static_pad) GST_FUNC(LIBGSTREAMER, gst_element_get_type) GST_FUNC(LIBGSTREAMER, gst_element_query_convert) GST_FUNC(LIBGSTREAMER, gst_element_query_duration) GST_FUNC(LIBGSTREAMER, gst_element_seek_simple) GST_FUNC(LIBGSTREAMER, gst_element_set_state) -GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment) GST_FUNC(LIBGSTREAMER, gst_flow_get_name) GST_FUNC(LIBGSTREAMER, gst_init) GST_FUNC(LIBGSTREAMER, gst_init_check) GST_FUNC(LIBGSTREAMER, gst_iterator_next) GST_FUNC(LIBGSTREAMER, gst_message_parse_error) GST_FUNC(LIBGSTREAMER, gst_message_type_get_name) -GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type) -GST_FUNC(LIBGSTREAMER, gst_mini_object_new) GST_FUNC(LIBGSTREAMER, gst_mini_object_ref) GST_FUNC(LIBGSTREAMER, gst_mini_object_unref) GST_FUNC(LIBGSTREAMER, gst_object_get_name) GST_FUNC(LIBGSTREAMER, gst_object_get_parent) GST_FUNC(LIBGSTREAMER, gst_object_unref) -GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe) -GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer) GST_FUNC(LIBGSTREAMER, gst_pad_get_element_private) -GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps) -GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function) GST_FUNC(LIBGSTREAMER, gst_pad_set_element_private) GST_FUNC(LIBGSTREAMER, gst_parse_bin_from_description) GST_FUNC(LIBGSTREAMER, gst_pipeline_get_bus) GST_FUNC(LIBGSTREAMER, gst_pipeline_get_type) GST_FUNC(LIBGSTREAMER, gst_plugin_feature_get_rank) GST_FUNC(LIBGSTREAMER, gst_registry_feature_filter) -GST_FUNC(LIBGSTREAMER, gst_registry_get_default) GST_FUNC(LIBGSTREAMER, gst_registry_get_feature_list_cookie) GST_FUNC(LIBGSTREAMER, gst_segment_init) -GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment) GST_FUNC(LIBGSTREAMER, gst_segment_to_stream_time) GST_FUNC(LIBGSTREAMER, gst_static_caps_get) GST_FUNC(LIBGSTREAMER, gst_structure_copy) @@ -85,11 +72,82 @@ GST_FUNC(LIBGSTREAMER, gst_structure_get_int) GST_FUNC(LIBGSTREAMER, gst_structure_get_value) GST_FUNC(LIBGSTREAMER, gst_structure_new) GST_FUNC(LIBGSTREAMER, gst_util_uint64_scale) + +#if GST_VERSION_MAJOR == 0 +GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer) +GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata) +GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc) +GST_FUNC(LIBGSTREAMER, gst_caps_unref) +GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass) +GST_FUNC(LIBGSTREAMER, gst_element_get_pad) +GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment) +GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type) +GST_FUNC(LIBGSTREAMER, gst_mini_object_new) +GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe) +GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer) +GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps) +GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function) +GST_FUNC(LIBGSTREAMER, gst_registry_get_default) +GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment) GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_height) GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_offset) GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_width) +GST_FUNC(LIBGSTVIDEO, gst_video_format_get_pixel_stride) GST_FUNC(LIBGSTVIDEO, gst_video_format_get_row_stride) GST_FUNC(LIBGSTVIDEO, gst_video_format_parse_caps) +#else + +GST_FUNC(LIBGSTAPP, gst_app_sink_pull_sample) +GST_FUNC(LIBGSTREAMER, _gst_caps_any) +GST_FUNC(LIBGSTREAMER, gst_allocator_get_type) +GST_FUNC(LIBGSTREAMER, gst_buffer_copy_into) +GST_FUNC(LIBGSTREAMER, gst_buffer_extract) +GST_FUNC(LIBGSTREAMER, gst_buffer_get_meta) +GST_FUNC(LIBGSTREAMER, gst_buffer_get_size) +GST_FUNC(LIBGSTREAMER, gst_buffer_map) +GST_FUNC(LIBGSTREAMER, gst_buffer_new_allocate) +GST_FUNC(LIBGSTREAMER, gst_buffer_n_memory) +GST_FUNC(LIBGSTREAMER, gst_buffer_peek_memory) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_acquire_buffer) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_allocator) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_params) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_config) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_type) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_is_active) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_active) +GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_config) +GST_FUNC(LIBGSTREAMER, gst_buffer_set_size) +GST_FUNC(LIBGSTREAMER, gst_buffer_unmap) +GST_FUNC(LIBGSTREAMER, gst_element_factory_get_metadata) +GST_FUNC(LIBGSTREAMER, gst_event_parse_segment) +GST_FUNC(LIBGSTREAMER, gst_memory_init) +GST_FUNC(LIBGSTREAMER, gst_memory_map) +GST_FUNC(LIBGSTREAMER, gst_memory_unmap) +GST_FUNC(LIBGSTREAMER, gst_object_get_type) +GST_FUNC(LIBGSTREAMER, gst_pad_add_probe) +GST_FUNC(LIBGSTREAMER, gst_pad_get_current_caps) +GST_FUNC(LIBGSTREAMER, gst_pad_probe_info_get_query) +GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_meta) +GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_param) +GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_pool) +GST_FUNC(LIBGSTREAMER, gst_query_parse_allocation) +GST_FUNC(LIBGSTREAMER, gst_registry_get) +GST_FUNC(LIBGSTREAMER, gst_sample_get_buffer) +GST_FUNC(LIBGSTREAMER, gst_segment_copy_into) +GST_FUNC(LIBGSTREAMER, gst_structure_free) +GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_config_get_video_alignment) +GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_has_option) +GST_FUNC(LIBGSTVIDEO, gst_video_buffer_pool_get_type) +GST_FUNC(LIBGSTVIDEO, gst_video_frame_map) +GST_FUNC(LIBGSTVIDEO, gst_video_frame_unmap) +GST_FUNC(LIBGSTVIDEO, gst_video_info_align) +GST_FUNC(LIBGSTVIDEO, gst_video_info_from_caps) +GST_FUNC(LIBGSTVIDEO, gst_video_info_init) +GST_FUNC(LIBGSTVIDEO, gst_video_meta_api_get_type) +GST_FUNC(LIBGSTVIDEO, gst_video_meta_map) +GST_FUNC(LIBGSTVIDEO, gst_video_meta_unmap) + +#endif /* * Functions that have been defined in the header file. We replace them so that @@ -99,6 +157,11 @@ GST_FUNC(LIBGSTVIDEO, gst_video_format_parse_caps) REPLACE_FUNC(gst_buffer_ref); REPLACE_FUNC(gst_buffer_unref); REPLACE_FUNC(gst_message_unref); + +#if GST_VERSION_MAJOR == 1 +REPLACE_FUNC(gst_caps_unref); +REPLACE_FUNC(gst_sample_unref); +#endif #endif #endif // !defined(__APPLE__) diff --git content/media/gstreamer/GStreamerLoader.cpp content/media/gstreamer/GStreamerLoader.cpp index 5961b23..e6457e0 100644 --- content/media/gstreamer/GStreamerLoader.cpp +++ content/media/gstreamer/GStreamerLoader.cpp @@ -6,13 +6,21 @@ #include #include -#include "GStreamerLoader.h" +#include "nsDebug.h" #include "mozilla/NullPtr.h" +#include "GStreamerLoader.h" + #define LIBGSTREAMER 0 #define LIBGSTAPP 1 #define LIBGSTVIDEO 2 +#ifdef __OpenBSD__ +#define LIB_GST_SUFFIX ".so" +#else +#define LIB_GST_SUFFIX ".so.0" +#endif + namespace mozilla { /* @@ -32,6 +40,11 @@ namespace mozilla { GstBuffer * gst_buffer_ref_impl(GstBuffer *buf); void gst_buffer_unref_impl(GstBuffer *buf); void gst_message_unref_impl(GstMessage *msg); +void gst_caps_unref_impl(GstCaps *caps); + +#if GST_VERSION_MAJOR == 1 +void gst_sample_unref_impl(GstSample *sample); +#endif bool load_gstreamer() @@ -58,32 +71,25 @@ load_gstreamer() if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) { gstreamerLib = RTLD_DEFAULT; } else { -#ifdef __OpenBSD__ - gstreamerLib = dlopen("libgstreamer-0.10.so", RTLD_NOW | RTLD_LOCAL); -#else - gstreamerLib = dlopen("libgstreamer-0.10.so.0", RTLD_NOW | RTLD_LOCAL); -#endif + gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL); } - void *handles[] = { + void *handles[3] = { gstreamerLib, -#ifdef __OpenBSD__ - dlopen("libgstapp-0.10.so", RTLD_NOW | RTLD_LOCAL), - dlopen("libgstvideo-0.10.so", RTLD_NOW | RTLD_LOCAL) -#else - dlopen("libgstapp-0.10.so.0", RTLD_NOW | RTLD_LOCAL), - dlopen("libgstvideo-0.10.so.0", RTLD_NOW | RTLD_LOCAL) -#endif + dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL), + dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL) }; for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) { if (!handles[i]) { + NS_WARNING("Couldn't link gstreamer libraries"); goto fail; } } #define GST_FUNC(lib, symbol) \ if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \ + NS_WARNING("Couldn't link symbol " #symbol); \ goto fail; \ } #define REPLACE_FUNC(symbol) symbol = symbol##_impl; @@ -123,4 +129,18 @@ gst_message_unref_impl(GstMessage *msg) gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg)); } +#if GST_VERSION_MAJOR == 1 +void +gst_sample_unref_impl(GstSample *sample) +{ + gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample)); +} +#endif + +void +gst_caps_unref_impl(GstCaps *caps) +{ + gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps)); +} + } diff --git content/media/gstreamer/GStreamerLoader.h content/media/gstreamer/GStreamerLoader.h index 2d801722..cd7fe6d 100644 --- content/media/gstreamer/GStreamerLoader.h +++ content/media/gstreamer/GStreamerLoader.h @@ -22,6 +22,11 @@ #include #pragma GCC diagnostic pop +#if GST_VERSION_MAJOR == 1 +#include +#include +#endif + namespace mozilla { /* @@ -42,4 +47,7 @@ bool load_gstreamer(); } +#undef GST_CAPS_ANY +#define GST_CAPS_ANY (*_gst_caps_any) + #endif // GStreamerLoader_h_ diff --git content/media/gstreamer/GStreamerReader-0.10.cpp content/media/gstreamer/GStreamerReader-0.10.cpp new file mode 100644 index 0000000..fb98bde --- /dev/null +++ content/media/gstreamer/GStreamerReader-0.10.cpp @@ -0,0 +1,203 @@ +#include "nsError.h" +#include "MediaDecoderStateMachine.h" +#include "AbstractMediaDecoder.h" +#include "MediaResource.h" +#include "GStreamerReader.h" +#include "GStreamerMozVideoBuffer.h" +#include "GStreamerFormatHelper.h" +#include "VideoUtils.h" +#include "mozilla/dom/TimeRanges.h" +#include "mozilla/Preferences.h" + +using namespace mozilla; +using mozilla::layers::PlanarYCbCrImage; +using mozilla::layers::ImageContainer; + +GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad, + guint64 aOffset, + guint aSize, + GstCaps* aCaps, + GstBuffer** aBuf) +{ + GStreamerReader* reader = reinterpret_cast(gst_pad_get_element_private(aPad)); + return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf); +} + +GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad, + guint64 aOffset, + guint aSize, + GstCaps* aCaps, + GstBuffer** aBuf) +{ + nsRefPtr image; + return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image); +} + +GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad, + guint64 aOffset, + guint aSize, + GstCaps* aCaps, + GstBuffer** aBuf, + nsRefPtr& aImage) +{ + /* allocate an image using the container */ + ImageContainer* container = mDecoder->GetImageContainer(); + if (!container) { + // We don't have an ImageContainer. We probably belong to an