mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 856308 - Enable GStreamer video buffer handling optimization for gstreamer versions older than 0.10.36. DONTBUILD because NPOTB r=alessandro.d,padenot
This commit is contained in:
parent
2b6efddc0c
commit
231cb29945
118
content/media/gstreamer/GStreamerMozVideoBuffer.cpp
Normal file
118
content/media/gstreamer/GStreamerMozVideoBuffer.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/* -*- 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"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static GstMozVideoBuffer *gst_moz_video_buffer_copy(GstMozVideoBuffer* self);
|
||||
static void gst_moz_video_buffer_finalize(GstMozVideoBuffer* self);
|
||||
|
||||
G_DEFINE_TYPE(GstMozVideoBuffer, gst_moz_video_buffer, GST_TYPE_BUFFER);
|
||||
|
||||
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), NULL);
|
||||
|
||||
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), NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
60
content/media/gstreamer/GStreamerMozVideoBuffer.h
Normal file
60
content/media/gstreamer/GStreamerMozVideoBuffer.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* 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 "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:
|
||||
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);
|
||||
}
|
||||
|
||||
nsRefPtr<layers::PlanarYCbCrImage> mImage;
|
||||
};
|
||||
|
||||
GType gst_moz_video_buffer_data_get_type (void);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* __GST_MOZ_VIDEO_BUFFER_H__ */
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "MediaResource.h"
|
||||
#include "GStreamerReader.h"
|
||||
#include "GStreamerFormatHelper.h"
|
||||
#include "GStreamerMozVideoBuffer.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "mozilla/dom/TimeRanges.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
@ -39,8 +40,6 @@ static const int SHORT_FILE_SIZE = 1024 * 1024;
|
||||
// The default resource->Read() size when working in push mode
|
||||
static const int DEFAULT_SOURCE_READ_SIZE = 50 * 1024;
|
||||
|
||||
G_DEFINE_BOXED_TYPE(BufferData, buffer_data, BufferData::Copy, BufferData::Free);
|
||||
|
||||
typedef enum {
|
||||
GST_PLAY_FLAG_VIDEO = (1 << 0),
|
||||
GST_PLAY_FLAG_AUDIO = (1 << 1),
|
||||
@ -139,9 +138,7 @@ nsresult GStreamerReader::Init(MediaDecoderReader* aCloneDonor)
|
||||
gst_pad_add_event_probe(sinkpad,
|
||||
G_CALLBACK(&GStreamerReader::EventProbeCb), this);
|
||||
gst_object_unref(sinkpad);
|
||||
#if GST_VERSION_MICRO >= 36
|
||||
gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb);
|
||||
#endif
|
||||
gst_pad_set_element_private(sinkpad, this);
|
||||
|
||||
mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! "
|
||||
@ -532,15 +529,11 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
|
||||
return false;
|
||||
|
||||
nsRefPtr<PlanarYCbCrImage> image;
|
||||
#if GST_VERSION_MICRO >= 36
|
||||
const GstStructure* structure = gst_buffer_get_qdata(buffer,
|
||||
g_quark_from_string("moz-reader-data"));
|
||||
const GValue* value = gst_structure_get_value(structure, "image");
|
||||
if (value) {
|
||||
BufferData* data = reinterpret_cast<BufferData*>(g_value_get_boxed(value));
|
||||
image = data->mImage;
|
||||
}
|
||||
#endif
|
||||
GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>
|
||||
GST_IS_MOZ_VIDEO_BUFFER(buffer)?gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(buffer)):nullptr;
|
||||
|
||||
if(bufferdata)
|
||||
image = bufferdata->mImage;
|
||||
|
||||
if (!image) {
|
||||
/* Ugh, upstream is not calling gst_pad_alloc_buffer(). Fallback to
|
||||
@ -844,29 +837,18 @@ GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad,
|
||||
nsRefPtr<PlanarYCbCrImage> image = dont_AddRef(img);
|
||||
|
||||
/* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */
|
||||
GstBuffer* buf = gst_buffer_new();
|
||||
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;
|
||||
|
||||
#if GST_VERSION_MICRO >= 36
|
||||
/* create a GBoxed handle to hold the image */
|
||||
BufferData* data = new BufferData(image);
|
||||
/* create a GstMozVideoBufferData to hold the image */
|
||||
GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image);
|
||||
|
||||
/* store it in a GValue so we can put it in a GstStructure */
|
||||
GValue value = {0,};
|
||||
g_value_init(&value, buffer_data_get_type());
|
||||
g_value_take_boxed(&value, data);
|
||||
|
||||
/* store the value in the structure */
|
||||
GstStructure* structure = gst_structure_new("moz-reader-data", nullptr);
|
||||
gst_structure_take_value(structure, "image", &value);
|
||||
|
||||
/* and attach the structure to the buffer */
|
||||
gst_buffer_set_qdata(buf, g_quark_from_string("moz-reader-data"), structure);
|
||||
#endif
|
||||
/* 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;
|
||||
|
@ -153,21 +153,6 @@ private:
|
||||
int fpsDen;
|
||||
};
|
||||
|
||||
class BufferData {
|
||||
public:
|
||||
BufferData(layers::PlanarYCbCrImage* aImage) : mImage(aImage) {}
|
||||
|
||||
static void* Copy(void* aData) {
|
||||
return new BufferData(reinterpret_cast<BufferData*>(aData)->mImage);
|
||||
}
|
||||
|
||||
static void Free(void* aData) {
|
||||
delete reinterpret_cast<BufferData*>(aData);
|
||||
}
|
||||
|
||||
nsRefPtr<layers::PlanarYCbCrImage> mImage;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@ CPPSRCS = \
|
||||
GStreamerReader.cpp \
|
||||
GStreamerDecoder.cpp \
|
||||
GStreamerFormatHelper.cpp \
|
||||
GStreamerMozVideoBuffer.cpp \
|
||||
$(NULL)
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
Loading…
Reference in New Issue
Block a user