зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1234092: P1. Remove GStreamer support. r=kentuckyfriedtakahe
It was now unused by default.
This commit is contained in:
Родитель
1ed3dc529a
Коммит
8f79430f0e
|
@ -24,10 +24,6 @@
|
|||
#include "RawDecoder.h"
|
||||
#include "RawReader.h"
|
||||
#endif
|
||||
#ifdef MOZ_GSTREAMER
|
||||
#include "GStreamerDecoder.h"
|
||||
#include "GStreamerReader.h"
|
||||
#endif
|
||||
#ifdef MOZ_ANDROID_OMX
|
||||
#include "AndroidMediaDecoder.h"
|
||||
#include "AndroidMediaReader.h"
|
||||
|
@ -172,23 +168,6 @@ DecoderTraits::IsWebMAudioType(const nsACString& aType)
|
|||
return aType.EqualsASCII("audio/webm");
|
||||
}
|
||||
|
||||
#ifdef MOZ_GSTREAMER
|
||||
static bool
|
||||
IsGStreamerSupportedType(const nsACString& aMimeType)
|
||||
{
|
||||
if (DecoderTraits::IsWebMTypeAndEnabled(aMimeType))
|
||||
return false;
|
||||
|
||||
if (!MediaDecoder::IsGStreamerEnabled())
|
||||
return false;
|
||||
|
||||
if (IsOggType(aMimeType) && !Preferences::GetBool("media.prefer-gstreamer", false))
|
||||
return false;
|
||||
|
||||
return GStreamerDecoder::CanHandleMediaType(aMimeType, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_OMX_DECODER
|
||||
static const char* const gOmxTypes[] = {
|
||||
"audio/mpeg",
|
||||
|
@ -498,12 +477,6 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
|
|||
if (IsAACSupportedType(nsDependentCString(aMIMEType))) {
|
||||
return CANPLAY_MAYBE;
|
||||
}
|
||||
#ifdef MOZ_GSTREAMER
|
||||
if (GStreamerDecoder::CanHandleMediaType(nsDependentCString(aMIMEType),
|
||||
aHaveRequestedCodecs ? &aRequestedCodecs : nullptr)) {
|
||||
return aHaveRequestedCodecs ? CANPLAY_YES : CANPLAY_MAYBE;
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_OMX_DECODER
|
||||
if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
|
||||
return CANPLAY_MAYBE;
|
||||
|
@ -550,12 +523,6 @@ InstantiateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
|
|||
decoder = new ADTSDecoder(aOwner);
|
||||
return decoder.forget();
|
||||
}
|
||||
#ifdef MOZ_GSTREAMER
|
||||
if (IsGStreamerSupportedType(aType)) {
|
||||
decoder = new GStreamerDecoder(aOwner);
|
||||
return decoder.forget();
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_RAW
|
||||
if (IsRawType(aType)) {
|
||||
decoder = new RawDecoder(aOwner);
|
||||
|
@ -650,11 +617,6 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
|
|||
if (IsAACSupportedType(aType)) {
|
||||
decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
|
||||
} else
|
||||
#ifdef MOZ_GSTREAMER
|
||||
if (IsGStreamerSupportedType(aType)) {
|
||||
decoderReader = new GStreamerReader(aDecoder);
|
||||
} else
|
||||
#endif
|
||||
#ifdef MOZ_RAW
|
||||
if (IsRawType(aType)) {
|
||||
decoderReader = new RawReader(aDecoder);
|
||||
|
@ -715,9 +677,6 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
|
|||
!IsB2GSupportOnlyType(aType)) ||
|
||||
#endif
|
||||
IsWebMSupportedType(aType) ||
|
||||
#ifdef MOZ_GSTREAMER
|
||||
IsGStreamerSupportedType(aType) ||
|
||||
#endif
|
||||
#ifdef MOZ_ANDROID_OMX
|
||||
(MediaDecoder::IsAndroidMediaEnabled() && IsAndroidMediaType(aType)) ||
|
||||
#endif
|
||||
|
|
|
@ -1662,14 +1662,6 @@ MediaDecoder::IsRtspEnabled()
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GSTREAMER
|
||||
bool
|
||||
MediaDecoder::IsGStreamerEnabled()
|
||||
{
|
||||
return Preferences::GetBool("media.gstreamer.enabled");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_OMX_DECODER
|
||||
bool
|
||||
MediaDecoder::IsOmxEnabled()
|
||||
|
|
|
@ -669,10 +669,6 @@ private:
|
|||
static bool IsRtspEnabled();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GSTREAMER
|
||||
static bool IsGStreamerEnabled();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_OMX_DECODER
|
||||
static bool IsOmxEnabled();
|
||||
#endif
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "GStreamerAllocator.h"
|
||||
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/video/gstvideometa.h>
|
||||
|
||||
#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;
|
||||
|
||||
// working around GTK+ bug https://bugzilla.gnome.org/show_bug.cgi?id=723899
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR);
|
||||
G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void
|
||||
moz_gfx_memory_reset(MozGfxMemory *mem)
|
||||
{
|
||||
if (mem->image)
|
||||
mem->image->Release();
|
||||
|
||||
ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer();
|
||||
mem->image = container->CreatePlanarYCbCrImage().forget().take();
|
||||
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;
|
||||
}
|
||||
|
||||
RefPtr<PlanarYCbCrImage>
|
||||
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
|
|
@ -1,25 +0,0 @@
|
|||
/* 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);
|
||||
RefPtr<layers::PlanarYCbCrImage> moz_gfx_memory_get_image(GstMemory *aMemory);
|
||||
|
||||
GType moz_gfx_buffer_pool_get_type();
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#include "MediaDecoderStateMachine.h"
|
||||
#include "GStreamerReader.h"
|
||||
#include "GStreamerDecoder.h"
|
||||
#include "GStreamerFormatHelper.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine()
|
||||
{
|
||||
return new MediaDecoderStateMachine(this, new GStreamerReader(this));
|
||||
}
|
||||
|
||||
bool
|
||||
GStreamerDecoder::CanHandleMediaType(const nsACString& aMIMEType,
|
||||
const nsAString* aCodecs)
|
||||
{
|
||||
return MediaDecoder::IsGStreamerEnabled() &&
|
||||
GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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(GStreamerDecoder_h_)
|
||||
#define GStreamerDecoder_h_
|
||||
|
||||
#include "MediaDecoder.h"
|
||||
#include "nsXPCOMStrings.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class GStreamerDecoder : public MediaDecoder
|
||||
{
|
||||
public:
|
||||
explicit GStreamerDecoder(MediaDecoderOwner* aOwner) : MediaDecoder(aOwner) {}
|
||||
virtual MediaDecoder* Clone(MediaDecoderOwner* aOwner) {
|
||||
return new GStreamerDecoder(aOwner);
|
||||
}
|
||||
virtual MediaDecoderStateMachine* CreateStateMachine();
|
||||
static bool CanHandleMediaType(const nsACString& aMIMEType, const nsAString* aCodecs);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,373 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#include "GStreamerFormatHelper.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsString.h"
|
||||
#include "GStreamerLoader.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#define ENTRY_FORMAT(entry) entry[0]
|
||||
#define ENTRY_CAPS(entry) entry[1]
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
extern LazyLogModule gMediaDecoderLog;
|
||||
#define LOG(msg, ...) \
|
||||
MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, ("GStreamerFormatHelper " msg, ##__VA_ARGS__))
|
||||
|
||||
GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr;
|
||||
bool GStreamerFormatHelper::sLoadOK = false;
|
||||
|
||||
GStreamerFormatHelper* GStreamerFormatHelper::Instance() {
|
||||
if (!gInstance) {
|
||||
if ((sLoadOK = load_gstreamer())) {
|
||||
gst_init(nullptr, nullptr);
|
||||
}
|
||||
|
||||
gInstance = new GStreamerFormatHelper();
|
||||
}
|
||||
|
||||
return gInstance;
|
||||
}
|
||||
|
||||
void GStreamerFormatHelper::Shutdown() {
|
||||
delete gInstance;
|
||||
gInstance = nullptr;
|
||||
}
|
||||
|
||||
static char const *const sContainers[][2] = {
|
||||
{"video/mp4", "video/quicktime"},
|
||||
{"video/x-m4v", "video/quicktime"},
|
||||
{"video/quicktime", "video/quicktime"},
|
||||
{"audio/mp4", "audio/x-m4a"},
|
||||
{"audio/x-m4a", "audio/x-m4a"},
|
||||
{"audio/mpeg", "audio/mpeg, mpegversion=(int)1"},
|
||||
{"audio/mp3", "audio/mpeg, mpegversion=(int)1"},
|
||||
};
|
||||
|
||||
static char const *const sCodecs[9][2] = {
|
||||
{"avc1.42E01E", "video/x-h264"},
|
||||
{"avc1.42001E", "video/x-h264"},
|
||||
{"avc1.58A01E", "video/x-h264"},
|
||||
{"avc1.4D401E", "video/x-h264"},
|
||||
{"avc1.64001E", "video/x-h264"},
|
||||
{"avc1.64001F", "video/x-h264"},
|
||||
{"mp4v.20.3", "video/3gpp"},
|
||||
{"mp4a.40.2", "audio/mpeg, mpegversion=(int)4"},
|
||||
{"mp3", "audio/mpeg, mpegversion=(int)1"},
|
||||
};
|
||||
|
||||
static char const * const sDefaultCodecCaps[][2] = {
|
||||
{"video/mp4", "video/x-h264"},
|
||||
{"video/x-m4v", "video/x-h264"},
|
||||
{"video/quicktime", "video/x-h264"},
|
||||
{"audio/mp4", "audio/mpeg, mpegversion=(int)4"},
|
||||
{"audio/x-m4a", "audio/mpeg, mpegversion=(int)4"},
|
||||
{"audio/mp3", "audio/mpeg, layer=(int)3"},
|
||||
{"audio/mpeg", "audio/mpeg, layer=(int)3"}
|
||||
};
|
||||
|
||||
static char const * const sPluginBlockList[] = {
|
||||
"flump3dec",
|
||||
"h264parse",
|
||||
};
|
||||
|
||||
GStreamerFormatHelper::GStreamerFormatHelper()
|
||||
: mFactories(nullptr),
|
||||
mCookie(static_cast<uint32_t>(-1))
|
||||
{
|
||||
if (!sLoadOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSupportedContainerCaps = gst_caps_new_empty();
|
||||
for (unsigned int i = 0; i < G_N_ELEMENTS(sContainers); i++) {
|
||||
const char* capsString = sContainers[i][1];
|
||||
GstCaps* caps = gst_caps_from_string(capsString);
|
||||
gst_caps_append(mSupportedContainerCaps, caps);
|
||||
}
|
||||
|
||||
mSupportedCodecCaps = gst_caps_new_empty();
|
||||
for (unsigned int i = 0; i < G_N_ELEMENTS(sCodecs); i++) {
|
||||
const char* capsString = sCodecs[i][1];
|
||||
GstCaps* caps = gst_caps_from_string(capsString);
|
||||
gst_caps_append(mSupportedCodecCaps, caps);
|
||||
}
|
||||
}
|
||||
|
||||
GStreamerFormatHelper::~GStreamerFormatHelper() {
|
||||
if (!sLoadOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
gst_caps_unref(mSupportedContainerCaps);
|
||||
gst_caps_unref(mSupportedCodecCaps);
|
||||
|
||||
if (mFactories)
|
||||
g_list_free(mFactories);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
GetContainerCapsFromMIMEType(const char *aType) {
|
||||
/* convert aMIMEType to gst container caps */
|
||||
const char* capsString = nullptr;
|
||||
for (uint32_t i = 0; i < G_N_ELEMENTS(sContainers); i++) {
|
||||
if (!strcmp(ENTRY_FORMAT(sContainers[i]), aType)) {
|
||||
capsString = ENTRY_CAPS(sContainers[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!capsString) {
|
||||
/* we couldn't find any matching caps */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return gst_caps_from_string(capsString);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
GetDefaultCapsFromMIMEType(const char *aType) {
|
||||
GstCaps *caps = GetContainerCapsFromMIMEType(aType);
|
||||
|
||||
for (uint32_t i = 0; i < G_N_ELEMENTS(sDefaultCodecCaps); i++) {
|
||||
if (!strcmp(sDefaultCodecCaps[i][0], aType)) {
|
||||
GstCaps *tmp = gst_caps_from_string(sDefaultCodecCaps[i][1]);
|
||||
|
||||
gst_caps_append(caps, tmp);
|
||||
return caps;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool GStreamerFormatHelper::CanHandleMediaType(const nsACString& aMIMEType,
|
||||
const nsAString* aCodecs) {
|
||||
if (!sLoadOK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *type;
|
||||
NS_CStringGetData(aMIMEType, &type, nullptr);
|
||||
|
||||
GstCaps *caps;
|
||||
if (aCodecs && !aCodecs->IsEmpty()) {
|
||||
caps = ConvertFormatsToCaps(type, aCodecs);
|
||||
} else {
|
||||
// Get a minimal set of codec caps for this MIME type we should support so
|
||||
// that we don't overreport MIME types we are able to play.
|
||||
caps = GetDefaultCapsFromMIMEType(type);
|
||||
}
|
||||
|
||||
if (!caps) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = HaveElementsToProcessCaps(caps);
|
||||
gst_caps_unref(caps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstCaps* GStreamerFormatHelper::ConvertFormatsToCaps(const char* aMIMEType,
|
||||
const nsAString* aCodecs) {
|
||||
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
|
||||
|
||||
unsigned int i;
|
||||
|
||||
GstCaps *caps = GetContainerCapsFromMIMEType(aMIMEType);
|
||||
if (!caps) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* container only */
|
||||
if (!aCodecs) {
|
||||
return caps;
|
||||
}
|
||||
|
||||
nsCharSeparatedTokenizer tokenizer(*aCodecs, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& codec = tokenizer.nextToken();
|
||||
const char *capsString = nullptr;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(sCodecs); i++) {
|
||||
if (codec.EqualsASCII(ENTRY_FORMAT(sCodecs[i]))) {
|
||||
capsString = ENTRY_CAPS(sCodecs[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!capsString) {
|
||||
gst_caps_unref(caps);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GstCaps* tmp = gst_caps_from_string(capsString);
|
||||
/* appends and frees tmp */
|
||||
gst_caps_append(caps, tmp);
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GStreamerFormatHelper::IsBlockListEnabled()
|
||||
{
|
||||
static bool sBlockListEnabled;
|
||||
static bool sBlockListEnabledCached = false;
|
||||
|
||||
if (!sBlockListEnabledCached) {
|
||||
Preferences::AddBoolVarCache(&sBlockListEnabled,
|
||||
"media.gstreamer.enable-blacklist", true);
|
||||
sBlockListEnabledCached = true;
|
||||
}
|
||||
|
||||
return sBlockListEnabled;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GStreamerFormatHelper::IsPluginFeatureBlocked(GstPluginFeature *aFeature)
|
||||
{
|
||||
if (!IsBlockListEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const gchar *factoryName =
|
||||
gst_plugin_feature_get_name(aFeature);
|
||||
|
||||
for (unsigned int i = 0; i < G_N_ELEMENTS(sPluginBlockList); i++) {
|
||||
if (!strcmp(factoryName, sPluginBlockList[i])) {
|
||||
LOG("rejecting disabled plugin %s", factoryName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static gboolean FactoryFilter(GstPluginFeature *aFeature, gpointer)
|
||||
{
|
||||
if (!GST_IS_ELEMENT_FACTORY(aFeature)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const gchar *className =
|
||||
gst_element_factory_get_klass(GST_ELEMENT_FACTORY_CAST(aFeature));
|
||||
|
||||
// NB: We skip filtering parsers here, because adding them to
|
||||
// the list can give false decoder positives to canPlayType().
|
||||
if (!strstr(className, "Decoder") && !strstr(className, "Demux")) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return
|
||||
gst_plugin_feature_get_rank(aFeature) >= GST_RANK_MARGINAL &&
|
||||
!GStreamerFormatHelper::IsPluginFeatureBlocked(aFeature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any |aFactory| caps intersect with |aCaps|
|
||||
*/
|
||||
static bool SupportsCaps(GstElementFactory *aFactory, GstCaps *aCaps)
|
||||
{
|
||||
for (const GList *iter = gst_element_factory_get_static_pad_templates(aFactory); iter; iter = iter->next) {
|
||||
GstStaticPadTemplate *templ = static_cast<GstStaticPadTemplate *>(iter->data);
|
||||
|
||||
if (templ->direction == GST_PAD_SRC) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GstCaps *caps = gst_static_caps_get(&templ->static_caps);
|
||||
if (!caps) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool supported = gst_caps_can_intersect(caps, aCaps);
|
||||
|
||||
gst_caps_unref(caps);
|
||||
|
||||
if (supported) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps* aCaps) {
|
||||
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
|
||||
|
||||
GList* factories = GetFactories();
|
||||
|
||||
/* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
|
||||
* caps structures individually as we want one element for _each_
|
||||
* structure */
|
||||
for (unsigned int i = 0; i < gst_caps_get_size(aCaps); i++) {
|
||||
GstStructure* s = gst_caps_get_structure(aCaps, i);
|
||||
GstCaps* caps = gst_caps_new_full(gst_structure_copy(s), nullptr);
|
||||
|
||||
bool found = false;
|
||||
for (GList *elem = factories; elem; elem = elem->next) {
|
||||
if (SupportsCaps(GST_ELEMENT_FACTORY_CAST(elem->data), caps)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gst_caps_unref(caps);
|
||||
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GStreamerFormatHelper::CanHandleContainerCaps(GstCaps* aCaps)
|
||||
{
|
||||
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
|
||||
|
||||
return gst_caps_can_intersect(aCaps, mSupportedContainerCaps);
|
||||
}
|
||||
|
||||
bool GStreamerFormatHelper::CanHandleCodecCaps(GstCaps* aCaps)
|
||||
{
|
||||
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
|
||||
|
||||
return gst_caps_can_intersect(aCaps, mSupportedCodecCaps);
|
||||
}
|
||||
|
||||
GList* GStreamerFormatHelper::GetFactories() {
|
||||
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
return mFactories;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -1,81 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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(GStreamerFormatHelper_h_)
|
||||
#define GStreamerFormatHelper_h_
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <mozilla/Types.h>
|
||||
#include "nsXPCOMStrings.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class GStreamerFormatHelper {
|
||||
/* This class can be used to query the GStreamer registry for the required
|
||||
* demuxers/decoders from nsHTMLMediaElement::CanPlayType.
|
||||
* It implements looking at the GstRegistry to check if elements to
|
||||
* demux/decode the formats passed to CanPlayType() are actually installed.
|
||||
*/
|
||||
public:
|
||||
static GStreamerFormatHelper* Instance();
|
||||
~GStreamerFormatHelper();
|
||||
|
||||
bool CanHandleMediaType(const nsACString& aMIMEType,
|
||||
const nsAString* aCodecs);
|
||||
|
||||
bool CanHandleContainerCaps(GstCaps* aCaps);
|
||||
bool CanHandleCodecCaps(GstCaps* aCaps);
|
||||
|
||||
static bool IsBlockListEnabled();
|
||||
static bool IsPluginFeatureBlocked(GstPluginFeature *aFeature);
|
||||
|
||||
static GstCaps* ConvertFormatsToCaps(const char* aMIMEType,
|
||||
const nsAString* aCodecs);
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
private:
|
||||
GStreamerFormatHelper();
|
||||
char* const *CodecListFromCaps(GstCaps* aCaps);
|
||||
bool HaveElementsToProcessCaps(GstCaps* aCaps);
|
||||
GList* GetFactories();
|
||||
|
||||
static GStreamerFormatHelper* gInstance;
|
||||
|
||||
/* table to convert from container MIME types to GStreamer caps */
|
||||
static char const *const mContainers[6][2];
|
||||
|
||||
/* table to convert from codec MIME types to GStreamer caps */
|
||||
static char const *const mCodecs[9][2];
|
||||
|
||||
/*
|
||||
* True iff we were able to find the proper GStreamer libs and the functions
|
||||
* we need.
|
||||
*/
|
||||
static bool sLoadOK;
|
||||
|
||||
/* whitelist of supported container/codec gst caps */
|
||||
GstCaps* mSupportedContainerCaps;
|
||||
GstCaps* mSupportedCodecCaps;
|
||||
|
||||
/* list of GStreamer element factories
|
||||
* Element factories are the basic types retrieved from the GStreamer
|
||||
* registry, they describe all plugins and elements that GStreamer can
|
||||
* create.
|
||||
* This means that element factories are useful for automated element
|
||||
* instancing, such as what autopluggers do,
|
||||
* and for creating lists of available elements. */
|
||||
GList* mFactories;
|
||||
|
||||
/* Storage for the default registrys feature list cookie.
|
||||
* It changes every time a feature is added to or removed from the
|
||||
* GStreamer registry. */
|
||||
uint32_t mCookie;
|
||||
};
|
||||
|
||||
} //namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,173 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef __APPLE__
|
||||
|
||||
/*
|
||||
* 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_set_callbacks)
|
||||
GST_FUNC(LIBGSTAPP, gst_app_src_end_of_stream)
|
||||
GST_FUNC(LIBGSTAPP, gst_app_src_get_size)
|
||||
GST_FUNC(LIBGSTAPP, gst_app_src_get_type)
|
||||
GST_FUNC(LIBGSTAPP, gst_app_src_push_buffer)
|
||||
GST_FUNC(LIBGSTAPP, gst_app_src_set_callbacks)
|
||||
GST_FUNC(LIBGSTAPP, gst_app_src_set_caps)
|
||||
GST_FUNC(LIBGSTAPP, gst_app_src_set_size)
|
||||
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_get_type)
|
||||
GST_FUNC(LIBGSTREAMER, gst_buffer_new)
|
||||
GST_FUNC(LIBGSTREAMER, gst_bus_set_sync_handler)
|
||||
GST_FUNC(LIBGSTREAMER, gst_bus_timed_pop_filtered)
|
||||
GST_FUNC(LIBGSTREAMER, gst_caps_append)
|
||||
GST_FUNC(LIBGSTREAMER, gst_caps_can_intersect)
|
||||
GST_FUNC(LIBGSTREAMER, gst_caps_from_string)
|
||||
GST_FUNC(LIBGSTREAMER, gst_caps_get_size)
|
||||
GST_FUNC(LIBGSTREAMER, gst_caps_get_structure)
|
||||
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_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_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_flow_get_name)
|
||||
GST_FUNC(LIBGSTREAMER, gst_init)
|
||||
GST_FUNC(LIBGSTREAMER, gst_init_check)
|
||||
GST_FUNC(LIBGSTREAMER, gst_iterator_free)
|
||||
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_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_get_element_private)
|
||||
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_plugin_feature_get_type)
|
||||
GST_FUNC(LIBGSTREAMER, gst_registry_feature_filter)
|
||||
GST_FUNC(LIBGSTREAMER, gst_registry_get_feature_list_cookie)
|
||||
GST_FUNC(LIBGSTREAMER, gst_segment_init)
|
||||
GST_FUNC(LIBGSTREAMER, gst_segment_to_stream_time)
|
||||
GST_FUNC(LIBGSTREAMER, gst_static_caps_get)
|
||||
GST_FUNC(LIBGSTREAMER, gst_structure_copy)
|
||||
GST_FUNC(LIBGSTREAMER, gst_structure_get_fraction)
|
||||
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_plugin_feature_get_name)
|
||||
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)
|
||||
GST_FUNC(LIBGSTVIDEO, gst_video_parse_caps_pixel_aspect_ratio)
|
||||
#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_event_type_get_name)
|
||||
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
|
||||
* they don't try to use the global gstreamer functions.
|
||||
*/
|
||||
#ifdef REPLACE_FUNC
|
||||
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__)
|
|
@ -1,145 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nsDebug.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 {
|
||||
|
||||
/*
|
||||
* Declare our function pointers using the types from the global gstreamer
|
||||
* definitions.
|
||||
*/
|
||||
#define GST_FUNC(_, func) typeof(::func)* func;
|
||||
#define REPLACE_FUNC(func) GST_FUNC(-1, func)
|
||||
#include "GStreamerFunctionList.h"
|
||||
#undef GST_FUNC
|
||||
#undef REPLACE_FUNC
|
||||
|
||||
/*
|
||||
* Redefinitions of functions that have been defined in the gstreamer headers to
|
||||
* stop them calling the gstreamer functions in global scope.
|
||||
*/
|
||||
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()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
return true;
|
||||
#endif
|
||||
static bool loaded = false;
|
||||
|
||||
if (loaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void *gstreamerLib = nullptr;
|
||||
guint major = 0;
|
||||
guint minor = 0;
|
||||
guint micro, nano;
|
||||
|
||||
typedef typeof(::gst_version) VersionFuncType;
|
||||
if (VersionFuncType *versionFunc = (VersionFuncType*)dlsym(RTLD_DEFAULT, "gst_version")) {
|
||||
versionFunc(&major, &minor, µ, &nano);
|
||||
}
|
||||
|
||||
if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) {
|
||||
gstreamerLib = RTLD_DEFAULT;
|
||||
} else {
|
||||
gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL);
|
||||
}
|
||||
|
||||
void *handles[3] = {
|
||||
gstreamerLib,
|
||||
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;
|
||||
#include "GStreamerFunctionList.h"
|
||||
#undef GST_FUNC
|
||||
#undef REPLACE_FUNC
|
||||
|
||||
loaded = true;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
|
||||
for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
|
||||
if (handles[i] && handles[i] != RTLD_DEFAULT) {
|
||||
dlclose(handles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GstBuffer *
|
||||
gst_buffer_ref_impl(GstBuffer *buf)
|
||||
{
|
||||
return (GstBuffer *)gst_mini_object_ref(GST_MINI_OBJECT_CAST(buf));
|
||||
}
|
||||
|
||||
void
|
||||
gst_buffer_unref_impl(GstBuffer *buf)
|
||||
{
|
||||
gst_mini_object_unref(GST_MINI_OBJECT_CAST(buf));
|
||||
}
|
||||
|
||||
void
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef GStreamerLoader_h_
|
||||
#define GStreamerLoader_h_
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/gstbuffer.h>
|
||||
#include <gst/gstelementfactory.h>
|
||||
#include <gst/gststructure.h>
|
||||
#include <gst/app/gstappsrc.h>
|
||||
#include <gst/app/gstappsink.h>
|
||||
// This include trips -Wreserved-user-defined-literal on clang. Ignoring it
|
||||
// trips -Wpragmas on GCC (unknown warning), but ignoring that trips
|
||||
// -Wunknown-pragmas on clang (unknown pragma).
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
#pragma GCC diagnostic ignored "-Wreserved-user-defined-literal"
|
||||
#include <gst/video/video.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#if GST_VERSION_MAJOR == 1
|
||||
#include <gst/video/gstvideometa.h>
|
||||
#include <gst/video/gstvideopool.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/*
|
||||
* dlopens the required libraries and dlsyms the functions we need.
|
||||
* Returns true on success, false otherwise.
|
||||
*/
|
||||
bool load_gstreamer();
|
||||
|
||||
/*
|
||||
* Declare our extern function pointers using the types from the global
|
||||
* gstreamer definitions.
|
||||
*/
|
||||
#define GST_FUNC(_, func) extern typeof(::func)* func;
|
||||
#define REPLACE_FUNC(func) GST_FUNC(-1, func)
|
||||
#include "GStreamerFunctionList.h"
|
||||
#undef GST_FUNC
|
||||
#undef REPLACE_FUNC
|
||||
|
||||
}
|
||||
|
||||
#undef GST_CAPS_ANY
|
||||
#define GST_CAPS_ANY (*_gst_caps_any)
|
||||
|
||||
#endif // GStreamerLoader_h_
|
|
@ -1,123 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#include <string.h>
|
||||
#include "GStreamerReader.h"
|
||||
#include "GStreamerMozVideoBuffer.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static GstMozVideoBuffer *gst_moz_video_buffer_copy(GstMozVideoBuffer* self);
|
||||
static void gst_moz_video_buffer_finalize(GstMozVideoBuffer* self);
|
||||
|
||||
// working around GTK+ bug https://bugzilla.gnome.org/show_bug.cgi?id=723899
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
G_DEFINE_TYPE(GstMozVideoBuffer, gst_moz_video_buffer, GST_TYPE_BUFFER);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
static void
|
||||
gst_moz_video_buffer_class_init(GstMozVideoBufferClass* klass)
|
||||
{
|
||||
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER_CLASS(klass));
|
||||
|
||||
GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS(klass);
|
||||
|
||||
mo_class->copy =(GstMiniObjectCopyFunction)gst_moz_video_buffer_copy;
|
||||
mo_class->finalize =(GstMiniObjectFinalizeFunction)gst_moz_video_buffer_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_moz_video_buffer_init(GstMozVideoBuffer* self)
|
||||
{
|
||||
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_moz_video_buffer_finalize(GstMozVideoBuffer* self)
|
||||
{
|
||||
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self));
|
||||
|
||||
if(self->data)
|
||||
g_boxed_free(GST_TYPE_MOZ_VIDEO_BUFFER_DATA, self->data);
|
||||
|
||||
GST_MINI_OBJECT_CLASS(gst_moz_video_buffer_parent_class)->finalize(GST_MINI_OBJECT(self));
|
||||
}
|
||||
|
||||
static GstMozVideoBuffer*
|
||||
gst_moz_video_buffer_copy(GstMozVideoBuffer* self)
|
||||
{
|
||||
GstMozVideoBuffer* copy;
|
||||
|
||||
g_return_val_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self), nullptr);
|
||||
|
||||
copy = gst_moz_video_buffer_new();
|
||||
|
||||
/* we simply copy everything from our parent */
|
||||
GST_BUFFER_DATA(GST_BUFFER_CAST(copy)) =
|
||||
(guint8*)g_memdup(GST_BUFFER_DATA(GST_BUFFER_CAST(self)), GST_BUFFER_SIZE(GST_BUFFER_CAST(self)));
|
||||
|
||||
/* make sure it gets freed(even if the parent is subclassed, we return a
|
||||
normal buffer) */
|
||||
GST_BUFFER_MALLOCDATA(GST_BUFFER_CAST(copy)) = GST_BUFFER_DATA(GST_BUFFER_CAST(copy));
|
||||
GST_BUFFER_SIZE(GST_BUFFER_CAST(copy)) = GST_BUFFER_SIZE(GST_BUFFER_CAST(self));
|
||||
|
||||
/* copy metadata */
|
||||
gst_buffer_copy_metadata(GST_BUFFER_CAST(copy),
|
||||
GST_BUFFER_CAST(self),
|
||||
(GstBufferCopyFlags)GST_BUFFER_COPY_ALL);
|
||||
/* copy videobuffer */
|
||||
if(self->data)
|
||||
copy->data = (GstMozVideoBufferData*)g_boxed_copy(GST_TYPE_MOZ_VIDEO_BUFFER_DATA, self->data);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
GstMozVideoBuffer*
|
||||
gst_moz_video_buffer_new(void)
|
||||
{
|
||||
GstMozVideoBuffer *self;
|
||||
|
||||
self =(GstMozVideoBuffer*)gst_mini_object_new(GST_TYPE_MOZ_VIDEO_BUFFER);
|
||||
self->data = nullptr;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gst_moz_video_buffer_set_data(GstMozVideoBuffer* self, GstMozVideoBufferData* data)
|
||||
{
|
||||
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self));
|
||||
|
||||
self->data = data;
|
||||
}
|
||||
|
||||
GstMozVideoBufferData*
|
||||
gst_moz_video_buffer_get_data(const GstMozVideoBuffer* self)
|
||||
{
|
||||
g_return_val_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self), nullptr);
|
||||
|
||||
return self->data;
|
||||
}
|
||||
|
||||
GType
|
||||
gst_moz_video_buffer_data_get_type(void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if(g_once_init_enter(&g_define_type_id__volatile)) {
|
||||
GType g_define_type_id =
|
||||
g_boxed_type_register_static(g_intern_static_string("GstMozVideoBufferData"),
|
||||
(GBoxedCopyFunc)GstMozVideoBufferData::Copy,
|
||||
(GBoxedFreeFunc)GstMozVideoBufferData::Free);
|
||||
g_once_init_leave(&g_define_type_id__volatile, g_define_type_id);
|
||||
}
|
||||
|
||||
return g_define_type_id__volatile;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#ifndef __GST_MOZ_VIDEO_BUFFER_H__
|
||||
#define __GST_MOZ_VIDEO_BUFFER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "GStreamerLoader.h"
|
||||
#include "MediaDecoderReader.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#define GST_TYPE_MOZ_VIDEO_BUFFER_DATA (gst_moz_video_buffer_data_get_type())
|
||||
#define GST_IS_MOZ_VIDEO_BUFFER_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_VIDEO_BUFFER_DATA))
|
||||
|
||||
#define GST_TYPE_MOZ_VIDEO_BUFFER (gst_moz_video_buffer_get_type())
|
||||
#define GST_IS_MOZ_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_VIDEO_BUFFER))
|
||||
#define GST_IS_MOZ_VIDEO_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MOZ_VIDEO_BUFFER))
|
||||
#define GST_MOZ_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MOZ_VIDEO_BUFFER, GstMozVideoBuffer))
|
||||
|
||||
typedef struct _GstMozVideoBuffer GstMozVideoBuffer;
|
||||
typedef struct _GstMozVideoBufferClass GstMozVideoBufferClass;
|
||||
|
||||
class GstMozVideoBufferData;
|
||||
|
||||
struct _GstMozVideoBuffer {
|
||||
GstBuffer buffer;
|
||||
GstMozVideoBufferData* data;
|
||||
};
|
||||
|
||||
struct _GstMozVideoBufferClass {
|
||||
GstBufferClass buffer_class;
|
||||
};
|
||||
|
||||
GType gst_moz_video_buffer_get_type(void);
|
||||
GstMozVideoBuffer* gst_moz_video_buffer_new(void);
|
||||
void gst_moz_video_buffer_set_data(GstMozVideoBuffer* buf, GstMozVideoBufferData* data);
|
||||
GstMozVideoBufferData* gst_moz_video_buffer_get_data(const GstMozVideoBuffer* buf);
|
||||
|
||||
class GstMozVideoBufferData {
|
||||
public:
|
||||
explicit GstMozVideoBufferData(layers::PlanarYCbCrImage* aImage) : mImage(aImage) {}
|
||||
|
||||
static void* Copy(void* aData) {
|
||||
return new GstMozVideoBufferData(reinterpret_cast<GstMozVideoBufferData*>(aData)->mImage);
|
||||
}
|
||||
|
||||
static void Free(void* aData) {
|
||||
delete reinterpret_cast<GstMozVideoBufferData*>(aData);
|
||||
}
|
||||
|
||||
RefPtr<layers::PlanarYCbCrImage> mImage;
|
||||
};
|
||||
|
||||
GType gst_moz_video_buffer_data_get_type (void);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* __GST_MOZ_VIDEO_BUFFER_H__ */
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
#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/Endian.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<GStreamerReader*>(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)
|
||||
{
|
||||
RefPtr<PlanarYCbCrImage> image;
|
||||
return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image);
|
||||
}
|
||||
|
||||
GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad,
|
||||
guint64 aOffset,
|
||||
guint aSize,
|
||||
GstCaps* aCaps,
|
||||
GstBuffer** aBuf,
|
||||
RefPtr<PlanarYCbCrImage>& aImage)
|
||||
{
|
||||
/* allocate an image using the container */
|
||||
ImageContainer* container = mDecoder->GetImageContainer();
|
||||
if (container == nullptr) {
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
RefPtr<PlanarYCbCrImage> image = container->CreatePlanarYCbCrImage();
|
||||
|
||||
/* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */
|
||||
GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new());
|
||||
GST_BUFFER_SIZE(buf) = aSize;
|
||||
/* allocate the actual YUV buffer */
|
||||
GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize);
|
||||
|
||||
aImage = image;
|
||||
|
||||
/* create a GstMozVideoBufferData to hold the image */
|
||||
GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image);
|
||||
|
||||
/* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */
|
||||
gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata);
|
||||
|
||||
*aBuf = buf;
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent)
|
||||
{
|
||||
GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad));
|
||||
switch(GST_EVENT_TYPE(aEvent)) {
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
{
|
||||
gboolean update;
|
||||
gdouble rate;
|
||||
GstFormat format;
|
||||
gint64 start, stop, position;
|
||||
GstSegment* segment;
|
||||
|
||||
/* Store the segments so we can convert timestamps to stream time, which
|
||||
* is what the upper layers sync on.
|
||||
*/
|
||||
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
|
||||
gst_event_parse_new_segment(aEvent, &update, &rate, &format,
|
||||
&start, &stop, &position);
|
||||
if (parent == GST_ELEMENT(mVideoAppSink))
|
||||
segment = &mVideoSegment;
|
||||
else
|
||||
segment = &mAudioSegment;
|
||||
gst_segment_set_newsegment(segment, update, rate, format,
|
||||
start, stop, position);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
/* Reset on seeks */
|
||||
ResetDecode();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gst_object_unref(parent);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean GStreamerReader::EventProbeCb(GstPad* aPad,
|
||||
GstEvent* aEvent,
|
||||
gpointer aUserData)
|
||||
{
|
||||
GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData);
|
||||
return reader->EventProbe(aPad, aEvent);
|
||||
}
|
||||
|
||||
RefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer)
|
||||
{
|
||||
if (!GST_IS_MOZ_VIDEO_BUFFER (aBuffer))
|
||||
return nullptr;
|
||||
|
||||
RefPtr<PlanarYCbCrImage> image;
|
||||
GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>(gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(aBuffer)));
|
||||
image = bufferdata->mImage;
|
||||
|
||||
PlanarYCbCrImage::Data data;
|
||||
data.mPicX = data.mPicY = 0;
|
||||
data.mPicSize = gfx::IntSize(mPicture.width, mPicture.height);
|
||||
data.mStereoMode = StereoMode::MONO;
|
||||
|
||||
data.mYChannel = GST_BUFFER_DATA(aBuffer);
|
||||
data.mYStride = gst_video_format_get_row_stride(mFormat, 0, mPicture.width);
|
||||
data.mYSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 0, mPicture.width),
|
||||
gst_video_format_get_component_height(mFormat, 0, mPicture.height));
|
||||
data.mYSkip = 0;
|
||||
data.mCbCrStride = gst_video_format_get_row_stride(mFormat, 1, mPicture.width);
|
||||
data.mCbCrSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 1, mPicture.width),
|
||||
gst_video_format_get_component_height(mFormat, 1, mPicture.height));
|
||||
data.mCbChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 1,
|
||||
mPicture.width, mPicture.height);
|
||||
data.mCrChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 2,
|
||||
mPicture.width, mPicture.height);
|
||||
data.mCbSkip = 0;
|
||||
data.mCrSkip = 0;
|
||||
|
||||
image->SetDataNoCopy(data);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer,
|
||||
GstBuffer** aOutBuffer,
|
||||
RefPtr<PlanarYCbCrImage> &aImage)
|
||||
{
|
||||
AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(aBuffer),
|
||||
GST_BUFFER_SIZE(aBuffer), nullptr, aOutBuffer, aImage);
|
||||
|
||||
gst_buffer_copy_metadata(*aOutBuffer, aBuffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL);
|
||||
memcpy(GST_BUFFER_DATA(*aOutBuffer), GST_BUFFER_DATA(aBuffer), GST_BUFFER_SIZE(*aOutBuffer));
|
||||
|
||||
aImage = GetImageFromBuffer(*aOutBuffer);
|
||||
}
|
||||
|
||||
GstCaps* GStreamerReader::BuildAudioSinkCaps()
|
||||
{
|
||||
GstCaps* caps;
|
||||
|
||||
#if MOZ_LITTLE_ENDIAN
|
||||
int endianness = 1234;
|
||||
#else
|
||||
int endianness = 4321;
|
||||
#endif
|
||||
|
||||
gint width;
|
||||
|
||||
#ifdef MOZ_SAMPLE_TYPE_FLOAT32
|
||||
caps = gst_caps_from_string("audio/x-raw-float, channels={1,2}");
|
||||
width = 32;
|
||||
#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */
|
||||
caps = gst_caps_from_string("audio/x-raw-int, channels={1,2}");
|
||||
width = 16;
|
||||
#endif
|
||||
|
||||
gst_caps_set_simple(caps,
|
||||
"width", G_TYPE_INT, width,
|
||||
"endianness", G_TYPE_INT, endianness,
|
||||
nullptr);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
void GStreamerReader::InstallPadCallbacks()
|
||||
{
|
||||
GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");
|
||||
gst_pad_add_event_probe(sinkpad,
|
||||
G_CALLBACK(&GStreamerReader::EventProbeCb), this);
|
||||
|
||||
gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb);
|
||||
gst_pad_set_element_private(sinkpad, this);
|
||||
gst_object_unref(sinkpad);
|
||||
|
||||
sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
|
||||
gst_pad_add_event_probe(sinkpad,
|
||||
G_CALLBACK(&GStreamerReader::EventProbeCb), this);
|
||||
gst_object_unref(sinkpad);
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,263 +0,0 @@
|
|||
/* 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(GStreamerReader_h_)
|
||||
#define GStreamerReader_h_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/app/gstappsrc.h>
|
||||
#include <gst/app/gstappsink.h>
|
||||
// This include trips -Wreserved-user-defined-literal on clang. Ignoring it
|
||||
// trips -Wpragmas on GCC (unknown warning), but ignoring that trips
|
||||
// -Wunknown-pragmas on clang (unknown pragma).
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
#pragma GCC diagnostic ignored "-Wreserved-user-defined-literal"
|
||||
#include <gst/video/video.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include "MediaDecoderReader.h"
|
||||
#include "MediaResource.h"
|
||||
#include "MP3FrameParser.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
struct GstURIDecodeBin;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class AbstractMediaDecoder;
|
||||
|
||||
class GStreamerReader : public MediaDecoderReader
|
||||
{
|
||||
typedef gfx::IntRect IntRect;
|
||||
|
||||
public:
|
||||
explicit GStreamerReader(AbstractMediaDecoder* aDecoder);
|
||||
virtual ~GStreamerReader();
|
||||
|
||||
virtual nsresult Init() override;
|
||||
virtual RefPtr<ShutdownPromise> Shutdown() override;
|
||||
virtual nsresult ResetDecode() override;
|
||||
virtual bool DecodeAudioData() override;
|
||||
virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
int64_t aTimeThreshold) override;
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) override;
|
||||
virtual RefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aEndTime) override;
|
||||
virtual media::TimeIntervals GetBuffered() override;
|
||||
|
||||
protected:
|
||||
virtual void NotifyDataArrivedInternal() override;
|
||||
|
||||
public:
|
||||
layers::ImageContainer* GetImageContainer() { return mDecoder->GetImageContainer(); }
|
||||
|
||||
private:
|
||||
bool HasAudio() { return mInfo.HasAudio(); }
|
||||
bool HasVideo() { return mInfo.HasVideo(); }
|
||||
void ReadAndPushData(guint aLength);
|
||||
RefPtr<layers::PlanarYCbCrImage> GetImageFromBuffer(GstBuffer* aBuffer);
|
||||
void CopyIntoImageBuffer(GstBuffer *aBuffer, GstBuffer** aOutBuffer, RefPtr<layers::PlanarYCbCrImage> &image);
|
||||
GstCaps* BuildAudioSinkCaps();
|
||||
void InstallPadCallbacks();
|
||||
|
||||
#if GST_VERSION_MAJOR >= 1
|
||||
void ImageDataFromVideoFrame(GstVideoFrame *aFrame, layers::PlanarYCbCrImage::Data *aData);
|
||||
#endif
|
||||
|
||||
/* Called once the pipeline is setup to check that the stream only contains
|
||||
* supported formats
|
||||
*/
|
||||
nsresult CheckSupportedFormats();
|
||||
|
||||
/* Gst callbacks */
|
||||
|
||||
static GstBusSyncReply ErrorCb(GstBus *aBus, GstMessage *aMessage, gpointer aUserData);
|
||||
GstBusSyncReply Error(GstBus *aBus, GstMessage *aMessage);
|
||||
|
||||
/*
|
||||
* We attach this callback to playbin so that when uridecodebin is
|
||||
* constructed, we can then list for its autoplug-sort signal to block
|
||||
* list the elements it can construct.
|
||||
*/
|
||||
static void ElementAddedCb(GstBin *aPlayBin,
|
||||
GstElement *aElement,
|
||||
gpointer aUserData);
|
||||
|
||||
/*
|
||||
* Called on the autoplug-sort signal emitted by uridecodebin for filtering
|
||||
* the elements it uses.
|
||||
*/
|
||||
static GValueArray *ElementFilterCb(GstURIDecodeBin *aBin,
|
||||
GstPad *aPad,
|
||||
GstCaps *aCaps,
|
||||
GValueArray *aFactories,
|
||||
gpointer aUserData);
|
||||
|
||||
GValueArray *ElementFilter(GstURIDecodeBin *aBin,
|
||||
GstPad *aPad,
|
||||
GstCaps *aCaps,
|
||||
GValueArray *aFactories);
|
||||
|
||||
/* Called on the source-setup signal emitted by playbin. Used to
|
||||
* configure appsrc .
|
||||
*/
|
||||
static void PlayBinSourceSetupCb(GstElement* aPlayBin,
|
||||
GParamSpec* pspec,
|
||||
gpointer aUserData);
|
||||
void PlayBinSourceSetup(GstAppSrc* aSource);
|
||||
|
||||
/* Called from appsrc when we need to read more data from the resource */
|
||||
static void NeedDataCb(GstAppSrc* aSrc, guint aLength, gpointer aUserData);
|
||||
void NeedData(GstAppSrc* aSrc, guint aLength);
|
||||
|
||||
/* Called when appsrc has enough data and we can stop reading */
|
||||
static void EnoughDataCb(GstAppSrc* aSrc, gpointer aUserData);
|
||||
void EnoughData(GstAppSrc* aSrc);
|
||||
|
||||
/* Called when a seek is issued on the pipeline */
|
||||
static gboolean SeekDataCb(GstAppSrc* aSrc,
|
||||
guint64 aOffset,
|
||||
gpointer aUserData);
|
||||
gboolean SeekData(GstAppSrc* aSrc, guint64 aOffset);
|
||||
|
||||
/* Called when events reach the sinks. See inline comments */
|
||||
#if GST_VERSION_MAJOR == 1
|
||||
static GstPadProbeReturn EventProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
|
||||
GstPadProbeReturn EventProbe(GstPad *aPad, GstEvent *aEvent);
|
||||
#else
|
||||
static gboolean EventProbeCb(GstPad* aPad, GstEvent* aEvent, gpointer aUserData);
|
||||
gboolean EventProbe(GstPad* aPad, GstEvent* aEvent);
|
||||
#endif
|
||||
|
||||
/* Called when the video part of the pipeline allocates buffers. Used to
|
||||
* provide PlanarYCbCrImage backed GstBuffers to the pipeline so that a memory
|
||||
* copy can be avoided when handling YUV buffers from the pipeline to the gfx
|
||||
* side.
|
||||
*/
|
||||
#if GST_VERSION_MAJOR == 1
|
||||
static GstPadProbeReturn QueryProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
|
||||
GstPadProbeReturn QueryProbe(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
|
||||
#else
|
||||
static GstFlowReturn AllocateVideoBufferCb(GstPad* aPad, guint64 aOffset, guint aSize,
|
||||
GstCaps* aCaps, GstBuffer** aBuf);
|
||||
GstFlowReturn AllocateVideoBufferFull(GstPad* aPad, guint64 aOffset, guint aSize,
|
||||
GstCaps* aCaps, GstBuffer** aBuf, RefPtr<layers::PlanarYCbCrImage>& aImage);
|
||||
GstFlowReturn AllocateVideoBuffer(GstPad* aPad, guint64 aOffset, guint aSize,
|
||||
GstCaps* aCaps, GstBuffer** aBuf);
|
||||
#endif
|
||||
|
||||
|
||||
/* Called when the pipeline is prerolled, that is when at start or after a
|
||||
* seek, the first audio and video buffers are queued in the sinks.
|
||||
*/
|
||||
static GstFlowReturn NewPrerollCb(GstAppSink* aSink, gpointer aUserData);
|
||||
void VideoPreroll();
|
||||
void AudioPreroll();
|
||||
|
||||
/* Called when buffers reach the sinks */
|
||||
static GstFlowReturn NewBufferCb(GstAppSink* aSink, gpointer aUserData);
|
||||
void NewVideoBuffer();
|
||||
void NewAudioBuffer();
|
||||
|
||||
/* Called at end of stream, when decoding has finished */
|
||||
static void EosCb(GstAppSink* aSink, gpointer aUserData);
|
||||
/* Notifies that a sink will no longer receive any more data. If nullptr
|
||||
* is passed to this, we'll assume all streams have reached EOS (for example
|
||||
* an error has occurred). */
|
||||
void Eos(GstAppSink* aSink = nullptr);
|
||||
|
||||
/* Called when an element is added inside playbin. We use it to find the
|
||||
* decodebin instance.
|
||||
*/
|
||||
static void PlayElementAddedCb(GstBin *aBin, GstElement *aElement,
|
||||
gpointer *aUserData);
|
||||
|
||||
/* Called during decoding, to decide whether a (sub)stream should be decoded or
|
||||
* ignored */
|
||||
static bool ShouldAutoplugFactory(GstElementFactory* aFactory, GstCaps* aCaps);
|
||||
|
||||
/* Called by decodebin during autoplugging. We use it to apply our
|
||||
* container/codec block list.
|
||||
*/
|
||||
static GValueArray* AutoplugSortCb(GstElement* aElement,
|
||||
GstPad* aPad, GstCaps* aCaps,
|
||||
GValueArray* aFactories);
|
||||
|
||||
// Try to find MP3 headers in this stream using our MP3 frame parser.
|
||||
nsresult ParseMP3Headers();
|
||||
|
||||
// Get the length of the stream, excluding any metadata we have ignored at the
|
||||
// start of the stream: ID3 headers, for example.
|
||||
int64_t GetDataLength();
|
||||
|
||||
// Use our own MP3 parser here, largely for consistency with other platforms.
|
||||
MP3FrameParser mMP3FrameParser;
|
||||
|
||||
// The byte position in the stream where the actual media (ignoring, for
|
||||
// example, ID3 tags) starts.
|
||||
uint64_t mDataOffset;
|
||||
|
||||
// We want to be able to decide in |ReadMetadata| whether or not we use the
|
||||
// duration from the MP3 frame parser, as this backend supports more than just
|
||||
// MP3. But |NotifyDataArrived| can update the duration and is often called
|
||||
// _before_ |ReadMetadata|. This flag stops the former from using the parser
|
||||
// duration until we are sure we want to.
|
||||
bool mUseParserDuration;
|
||||
int64_t mLastParserDuration;
|
||||
|
||||
#if GST_VERSION_MAJOR >= 1
|
||||
GstAllocator *mAllocator;
|
||||
GstBufferPool *mBufferPool;
|
||||
GstVideoInfo mVideoInfo;
|
||||
#endif
|
||||
GstElement* mPlayBin;
|
||||
GstBus* mBus;
|
||||
GstAppSrc* mSource;
|
||||
/* video sink bin */
|
||||
GstElement* mVideoSink;
|
||||
/* the actual video app sink */
|
||||
GstAppSink* mVideoAppSink;
|
||||
/* audio sink bin */
|
||||
GstElement* mAudioSink;
|
||||
/* the actual audio app sink */
|
||||
GstAppSink* mAudioAppSink;
|
||||
GstVideoFormat mFormat;
|
||||
IntRect mPicture;
|
||||
int mVideoSinkBufferCount;
|
||||
int mAudioSinkBufferCount;
|
||||
GstAppSrcCallbacks mSrcCallbacks;
|
||||
GstAppSinkCallbacks mSinkCallbacks;
|
||||
/* monitor used to synchronize access to shared state between gstreamer
|
||||
* threads and other gecko threads */
|
||||
ReentrantMonitor mGstThreadsMonitor;
|
||||
/* video and audio segments we use to convert absolute timestamps to [0,
|
||||
* stream_duration]. They're set when the pipeline is started or after a seek.
|
||||
* Concurrent access guarded with mGstThreadsMonitor.
|
||||
*/
|
||||
GstSegment mVideoSegment;
|
||||
GstSegment mAudioSegment;
|
||||
/* bool used to signal when gst has detected the end of stream and
|
||||
* DecodeAudioData and DecodeVideoFrame should not expect any more data
|
||||
*/
|
||||
bool mReachedAudioEos;
|
||||
bool mReachedVideoEos;
|
||||
#if GST_VERSION_MAJOR >= 1
|
||||
bool mConfigureAlignment;
|
||||
#endif
|
||||
int fpsNum;
|
||||
int fpsDen;
|
||||
|
||||
MediaResourceIndex mResource;
|
||||
MediaByteRangeSet mLastCachedRanges;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
EXPORTS += [
|
||||
'GStreamerDecoder.h',
|
||||
'GStreamerFormatHelper.h',
|
||||
'GStreamerLoader.h',
|
||||
'GStreamerReader.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'GStreamerDecoder.cpp',
|
||||
'GStreamerFormatHelper.cpp',
|
||||
'GStreamerLoader.cpp',
|
||||
'GStreamerReader.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['GST_API_VERSION'] == '1.0':
|
||||
SOURCES += [
|
||||
'GStreamerAllocator.cpp',
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
'GStreamerMozVideoBuffer.cpp',
|
||||
'GStreamerReader-0.10.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
'/dom/html',
|
||||
]
|
||||
|
||||
CFLAGS += CONFIG['GSTREAMER_CFLAGS']
|
||||
CXXFLAGS += CONFIG['GSTREAMER_CFLAGS']
|
|
@ -42,9 +42,6 @@ DIRS += [
|
|||
if CONFIG['MOZ_RAW']:
|
||||
DIRS += ['raw']
|
||||
|
||||
if CONFIG['MOZ_GSTREAMER']:
|
||||
DIRS += ['gstreamer']
|
||||
|
||||
if CONFIG['MOZ_DIRECTSHOW']:
|
||||
DIRS += ['directshow']
|
||||
|
||||
|
@ -312,9 +309,6 @@ if CONFIG['ANDROID_VERSION'] > '15':
|
|||
if CONFIG['MOZ_GONK_MEDIACODEC']:
|
||||
DEFINES['MOZ_GONK_MEDIACODEC'] = True
|
||||
|
||||
CFLAGS += CONFIG['GSTREAMER_CFLAGS']
|
||||
CXXFLAGS += CONFIG['GSTREAMER_CFLAGS']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
# Suppress some GCC warnings being treated as errors:
|
||||
|
|
|
@ -128,7 +128,6 @@ var haveMp4 = (getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
|
|||
IsMacOSSnowLeopardOrLater() ||
|
||||
IsJellyBeanOrLater() ||
|
||||
getPref("media.omx.enabled") ||
|
||||
getPref("media.gstreamer.enabled") ||
|
||||
getPref("media.ffmpeg.enabled");
|
||||
|
||||
check_mp4(document.getElementById('v'), haveMp4);
|
||||
|
@ -136,7 +135,6 @@ check_mp4(document.getElementById('v'), haveMp4);
|
|||
var haveMp3 = getPref("media.directshow.enabled") ||
|
||||
(getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
|
||||
(IsJellyBeanOrLater() && getPref("media.android-media-codec.enabled")) ||
|
||||
getPref("media.gstreamer.enabled") ||
|
||||
getPref("media.ffmpeg.enabled") ||
|
||||
getPref("media.apple.mp3.enabled");
|
||||
check_mp3(document.getElementById('v'), haveMp3);
|
||||
|
|
|
@ -120,10 +120,6 @@ if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
|
|||
'/media/sphinxbase',
|
||||
]
|
||||
|
||||
|
||||
if CONFIG['MOZ_GSTREAMER']:
|
||||
CXXFLAGS += CONFIG['GSTREAMER_CFLAGS']
|
||||
|
||||
if CONFIG['MOZ_SECUREELEMENT']:
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/secureelement',
|
||||
|
|
|
@ -97,10 +97,6 @@
|
|||
#include "AndroidMediaPluginHost.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GSTREAMER
|
||||
#include "GStreamerFormatHelper.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_FFMPEG
|
||||
#include "FFmpegRuntimeLinker.h"
|
||||
#endif
|
||||
|
@ -397,10 +393,6 @@ nsLayoutStatics::Shutdown()
|
|||
AndroidMediaPluginHost::Shutdown();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GSTREAMER
|
||||
GStreamerFormatHelper::Shutdown();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_FFMPEG
|
||||
FFmpegRuntimeLinker::Unlink();
|
||||
#endif
|
||||
|
|
|
@ -341,10 +341,6 @@ pref("media.webm.enabled", true);
|
|||
pref("media.webm.intel_decoder.enabled", false);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_GSTREAMER
|
||||
pref("media.gstreamer.enabled", true);
|
||||
pref("media.gstreamer.enable-blacklist", true);
|
||||
#endif
|
||||
#ifdef MOZ_APPLEMEDIA
|
||||
#ifdef MOZ_WIDGET_UIKIT
|
||||
pref("media.mp3.enabled", true);
|
||||
|
|
|
@ -368,9 +368,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
if CONFIG['MOZ_ENABLE_QT']:
|
||||
OS_LIBS += CONFIG['XEXT_LIBS']
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' and CONFIG['MOZ_GSTREAMER']:
|
||||
OS_LIBS += CONFIG['GSTREAMER_LIBS']
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
OS_LIBS += [
|
||||
'usp10',
|
||||
|
|
|
@ -520,7 +520,7 @@ static nsDefaultMimeTypeEntry defaultMimeEntries [] =
|
|||
{ AUDIO_OGG, "opus" },
|
||||
{ VIDEO_WEBM, "webm" },
|
||||
{ AUDIO_WEBM, "webm" },
|
||||
#if defined(MOZ_GSTREAMER) || defined(MOZ_WMF)
|
||||
#if defined(MOZ_WMF)
|
||||
{ VIDEO_MP4, "mp4" },
|
||||
{ AUDIO_MP4, "m4a" },
|
||||
{ AUDIO_MP3, "mp3" },
|
||||
|
|
Загрузка…
Ссылка в новой задаче