Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RDI-2056 #52

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -546,3 +546,76 @@ EMSCRIPTEN_BINDINGS (gst_web_transport_src)
function ("gst_web_utils_js_worker_transfer_object",
&gst_web_utils_js_worker_transfer_object);
}

GstVideoFormat
gst_web_utils_video_format_from_web_format (const char *vf_format)
{
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;

// TODO: gst_video_format_from_string?

if (!g_strcmp0 (vf_format, "I420")) {
format = GST_VIDEO_FORMAT_I420;
} else if (!g_strcmp0 (vf_format, "I420A")) {
format = GST_VIDEO_FORMAT_A420;
} else if (!g_strcmp0 (vf_format, "I422")) {
format = GST_VIDEO_FORMAT_Y42B;
} else if (!g_strcmp0 (vf_format, "I444")) {
format = GST_VIDEO_FORMAT_Y444;
} else if (!g_strcmp0 (vf_format, "NV12")) {
format = GST_VIDEO_FORMAT_NV12;
} else if (!g_strcmp0 (vf_format, "RGBA")) {
format = GST_VIDEO_FORMAT_RGBA;
} else if (!g_strcmp0 (vf_format, "RGBX")) {
format = GST_VIDEO_FORMAT_RGBx;
} else if (!g_strcmp0 (vf_format, "BGRA")) {
format = GST_VIDEO_FORMAT_BGRA;
} else if (!g_strcmp0 (vf_format, "BGRX")) {
format = GST_VIDEO_FORMAT_BGRx;
} else {
GST_ERROR ("Unsupported format %s", vf_format);
}

return format;
}

const char *
gst_web_utils_video_format_to_web_format (GstVideoFormat format)
{
const char *vf_format = NULL;

switch (format) {
case GST_VIDEO_FORMAT_I420:
vf_format = "I420";
break;
case GST_VIDEO_FORMAT_A420:
vf_format = "I420A";
break;
case GST_VIDEO_FORMAT_Y42B:
vf_format = "I422";
break;
case GST_VIDEO_FORMAT_Y444:
vf_format = "I444";
break;
case GST_VIDEO_FORMAT_NV12:
vf_format = "NV12";
break;
case GST_VIDEO_FORMAT_RGBA:
vf_format = "RGBA";
break;
case GST_VIDEO_FORMAT_RGBx:
vf_format = "RGBX";
break;
case GST_VIDEO_FORMAT_BGRA:
vf_format = "BGRA";
break;
case GST_VIDEO_FORMAT_BGRx:
vf_format = "BGRX";
break;
default:
GST_ERROR ("Unsupported GstVideoFormat: %d", format);
break;
}

return vf_format;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef __GST_WEB_UTILS_H__
#define __GST_WEB_UTILS_H__

#include <gst/video/video.h>
#include "gstwebcanvas.h"

#define GST_WEB_UTILS_MESSAGE_PROPOSE_OBJECT_NAME "GstWebProposeObjectMessage"
Expand All @@ -44,9 +45,11 @@ void gst_web_utils_js_register_on_message (void);
void gst_web_utils_js_unregister_on_message (void);
void gst_web_utils_element_process_request_object (
GstElement *e, GstMessage *msg, guintptr object);

GstMessage *gst_web_utils_message_new_request_object (GstElement *src,
const gchar *cb_name, const gchar *object_name, gpointer user_data);
GstVideoFormat gst_web_utils_video_format_from_web_format (
const char *vf_format);
const char *gst_web_utils_video_format_to_web_format (GstVideoFormat format);

G_END_DECLS

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@
#endif

#include <gst/gst.h>
#include <emscripten.h>
#include <emscripten/bind.h>
#include <gst/video/gstvideometa.h>
#include <gst/web/gstwebutils.h>

#include "gstwebrunner.h"
#include "gstwebvideoframe.h"
Expand Down Expand Up @@ -65,6 +68,7 @@ struct _GstWebVideoFramePrivate
GstWebRunner *runner;
/* The Emscripten's JS VideoFrame */
val video_frame;
guint8 *data;
};

typedef struct _GstWebVideoFrameAllocator
Expand All @@ -77,6 +81,15 @@ typedef struct _GstWebVideoFrameAllocatorClass
GstAllocatorClass parent_class;
} GstWebVideoFrameAllocatorClass;

typedef struct _GstWebVideoFrameAllocatorMapCpuData
{
GstWebVideoFrame *self;
guint8 *data;
gsize size;
GstVideoInfo *info;
gboolean result;
} GstWebVideoFrameAllocatorMapCpuData;

typedef struct _GstWebVideoFrameAllocationSizeData
{
val video_frame;
Expand Down Expand Up @@ -109,20 +122,105 @@ GST_DEFINE_MINI_OBJECT_TYPE (GstWebVideoFrame, gst_web_video_frame);
G_DEFINE_TYPE (GstWebVideoFrameAllocator, gst_web_video_frame_allocator,
GST_TYPE_ALLOCATOR);

static gboolean
gst_web_video_frame_map_internal (
GstWebVideoFrame *self, GstVideoInfo *info, gpointer data, gsize size)
{
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (
info == NULL || (info != NULL && info->finfo != NULL), FALSE);
aslobodeniuk marked this conversation as resolved.
Show resolved Hide resolved
g_return_val_if_fail (data != NULL, FALSE);

val video_frame = gst_web_video_frame_get_handle (self);
val data_view =
val (typed_memory_view<uint8_t> (size, static_cast<uint8_t *> (data)));
val options = val::object ();

if (info != NULL) {
const char *format;

format = gst_web_utils_video_format_to_web_format (
GST_VIDEO_FORMAT_INFO_FORMAT (info->finfo));
if (format == NULL) {
GST_ERROR ("Format %s is not supported.",
GST_VIDEO_FORMAT_INFO_NAME (info->finfo));
return FALSE;
}
options.set ("format", format);
} else {
GST_DEBUG ("No format specified. Use default format.");
}

video_frame.call<val> ("copyTo", data_view, options).await ();

return TRUE;
}

static void
gst_web_video_frame_allocator_map_cpu_access (gpointer data)
{
GstWebVideoFrameAllocatorMapCpuData *cdata =
(GstWebVideoFrameAllocatorMapCpuData *) data;
GstWebVideoFrame *self = cdata->self;

cdata->result = gst_web_video_frame_map_internal (
self, cdata->info, cdata->data, cdata->size);
}

gboolean
gst_web_video_frame_copy_to (
GstWebVideoFrame *self, GstVideoInfo *info, guint8 *data, gsize size)
{
GstWebVideoFrameAllocatorMapCpuData cdata = { .self = self,
.data = data,
.size = info->size,
.info = info,
.result = FALSE };

g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (info != NULL, FALSE);

gst_web_runner_send_message (self->priv->runner,
gst_web_video_frame_allocator_map_cpu_access, &cdata);

return cdata.result;
}

static gpointer
gst_web_video_frame_allocator_map_full (
GstWebVideoFrame *mem, GstMapInfo *info, gsize size)
GstWebVideoFrame *self, GstMapInfo *info, gsize size)
{
GST_FIXME ("Trying to map");
GstWebVideoFrameAllocatorMapCpuData data = {
.self = self, .info = NULL, .result = FALSE
};

return NULL;
if ((info->flags & GST_MAP_WRITE) == GST_MAP_WRITE) {
GST_DEBUG ("Write flags not supported");
return NULL;
}

if (self->priv->data)
goto beach;

data.data = self->priv->data = (guint8 *) g_malloc (size);
data.size = size;

gst_web_runner_send_message (
self->priv->runner, gst_web_video_frame_allocator_map_cpu_access, &data);

if (!data.result) {
return NULL;
}

beach:
return self->priv->data;
}

static void
gst_web_video_frame_allocator_unmap_full (
GstWebVideoFrame *mem, GstMapInfo *info)
{
GST_FIXME ("Trying to unmap");
/* Nothing to do. */
}

static GstMemory *
Expand Down Expand Up @@ -159,6 +257,7 @@ gst_web_video_frame_allocator_alloc (
mem->priv = g_new0 (GstWebVideoFramePrivate, 1);
mem->priv->video_frame = vf_params->video_frame;
mem->priv->runner = vf_params->runner;
mem->priv->data = NULL;

/* Chain the memory init */
/* We need to get the allocationSize from the video_frame to know the buffer
Expand All @@ -182,6 +281,7 @@ gst_web_video_frame_allocator_free (GstAllocator *allocator, GstMemory *memory)

gst_object_unref (self->priv->runner);
self->priv->video_frame = val::undefined ();
g_free (self->priv->data);
g_free (self->priv);
}

Expand Down
4 changes: 4 additions & 0 deletions gst.wasm/subprojects/gst-plugins-web/gst/web/gstweb.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "gstwebstreamsrc.h"
#include "gstwebcanvassink.h"
#include "gstwebcanvassrc.h"
#include "gstwebdownload.h"

#include "codecs/gstwebcodecs.h"
#include "transport/gstwebtransportsrc.h"

Expand All @@ -47,6 +49,8 @@ plugin_init (GstPlugin *plugin)
gst_element_register_web_fetch_src (plugin);
gst_element_register_web_stream_src (plugin);
gst_element_register_web_transport_src (plugin);
gst_element_register_web_download (plugin);

return TRUE;
}

Expand Down
Loading
Loading