Skip to content

Commit

Permalink
Add webdownload element
Browse files Browse the repository at this point in the history
  • Loading branch information
cfoch committed Nov 5, 2024
1 parent 982f69c commit 34dcb85
Show file tree
Hide file tree
Showing 13 changed files with 558 additions and 7 deletions.
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_convert_video_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_convert_video_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 @@ -77,6 +80,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 +121,99 @@ 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);
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_convert_video_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, .data = NULL, .size = size, .info = NULL, .result = FALSE
};

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

data.data = (guint8 *) g_malloc (data.size);

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

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

return data.data;
}

static void
gst_web_video_frame_allocator_unmap_full (
GstWebVideoFrame *mem, GstMapInfo *info)
{
GST_FIXME ("Trying to unmap");
g_free (info->data);
}

static GstMemory *
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

0 comments on commit 34dcb85

Please sign in to comment.