[vlc-devel] [PATCH 45/45] Emscripten JS FETCH API plugin and websocket_to_posix_proxy support.

Gokhan Poyraz gokhanp at gmail.com
Wed Jan 18 09:55:48 UTC 2023


---
 .../0082-emscripten_js_fetch_api_plugin.patch | 152 +++++++++++++++
 ..._sockets_over_websocket_proxy_server.patch | 183 ++++++++++++++++++
 2 files changed, 335 insertions(+)
 create mode 100644 vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch
 create mode 100644 vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch

diff --git a/vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch b/vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch
new file mode 100644
index 0000000..b1afadc
--- /dev/null
+++ b/vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch
@@ -0,0 +1,152 @@
+diff -Nuar vlc.original/modules/access/Makefile.am vlc/modules/access/Makefile.am
+--- vlc.original/modules/access/Makefile.am	2022-12-15 20:28:36.000000000 +0300
++++ vlc/modules/access/Makefile.am	2022-12-12 13:59:11.000000000 +0300
+@@ -29,6 +29,9 @@
+ if HAVE_EMSCRIPTEN
+ libemjsfile_plugin_la_SOURCES = access/emjsfile.c
+ access_LTLIBRARIES += libemjsfile_plugin.la
++
++libemjsfetch_plugin_la_SOURCES = access/emjsfetch.c
++access_LTLIBRARIES += libemjsfetch_plugin.la
+ endif
+ 
+ libidummy_plugin_la_SOURCES = access/idummy.c
+diff -Nuar vlc.original/modules/access/emjsfetch.c vlc/modules/access/emjsfetch.c
+--- vlc.original/modules/access/emjsfetch.c	1970-01-01 02:00:00.000000000 +0200
++++ vlc/modules/access/emjsfetch.c	2022-12-15 20:24:49.000000000 +0300
+@@ -0,0 +1,135 @@
++/*****************************************************************************
++ * emjsfetch.c: emscripten js fetch api plugin
++ *****************************************************************************
++ * Copyright (C) 2022 VLC authors Videolabs, and VideoLAN
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Lesser General Public License as published by
++ * the Free Software Foundation; either version 2.1 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
++ *****************************************************************************/
++
++#ifdef HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include <vlc_common.h>
++#include <vlc_plugin.h>
++#include <vlc_access.h>
++#include <vlc_threads.h>
++#include <stdalign.h>
++
++#include <emscripten.h>
++
++#include <stdio.h>
++#include <errno.h>
++#include <string.h>
++#include <unistd.h>
++
++typedef struct
++{   
++    char *url;
++} access_sys_t;
++
++static block_t *BlockFetch(stream_t *p_access, bool *restrict eof)
++{
++    access_sys_t *p_sys = p_access->p_sys;
++    int rc, fz;
++    void *ebuf;
++    block_t *pkt = NULL;
++
++    msg_Dbg( p_access, "fetch: start(%s)", p_sys->url);
++    emscripten_wget_data(p_sys->url, &ebuf, &fz, &rc);
++    if (rc != 0) {
++       msg_Dbg( p_access, "fetch: unable to fetch(%s), err: %d", p_sys->url, rc);
++       return pkt;
++    }
++
++    msg_Dbg( p_access, "fetch: %d byte(s)", fz);
++
++    pkt = block_Alloc( fz );
++    if ( unlikely( pkt == NULL ) ) {   
++       msg_Dbg( p_access, "fetch: block_Alloc(%s) failed", p_sys->url);
++       return NULL;
++    }
++    memcpy(pkt->p_buffer, ebuf, fz);
++    pkt->i_buffer = fz;
++
++    free(ebuf);
++    *eof = true;
++    return pkt;
++}
++
++static int Control( stream_t *p_access, int i_query, va_list args )
++{
++    int i_ret = VLC_SUCCESS;
++
++    switch( i_query )
++    {
++        case STREAM_CAN_SEEK:
++        case STREAM_CAN_FASTSEEK:
++        case STREAM_CAN_PAUSE:
++        case STREAM_CAN_CONTROL_PACE:
++            *va_arg( args, bool * ) = false;
++            break;
++        case STREAM_GET_PTS_DELAY:
++            *va_arg( args, vlc_tick_t * ) = VLC_TICK_FROM_MS(
++                   var_InheritInteger(p_access, "network-caching") );
++            break;
++        default:
++            i_ret = VLC_EGENERIC;
++            break;
++    }
++
++    return i_ret;
++}
++
++static void EmFetchClose (vlc_object_t * p_this) {
++    stream_t *p_access = (stream_t*)p_this;
++    access_sys_t *p_sys = p_access->p_sys;
++    free(p_sys->url);
++}
++
++static int EmFetchOpen( vlc_object_t *p_this ) {
++    stream_t *p_access = (stream_t*)p_this;
++
++    access_sys_t *p_sys = vlc_obj_malloc(p_this, sizeof (*p_sys));
++    if (unlikely(p_sys == NULL))
++        return VLC_ENOMEM;
++
++    msg_Dbg( p_access, "fetch: base url='%s'", p_access->psz_url);
++
++    if (p_access->psz_url[0] == 'f') {
++       p_sys->url = strdup(p_access->psz_url + 8);
++    } else {
++       p_sys->url = strdup(p_access->psz_url);
++    }
++    p_access->p_sys = p_sys;
++    
++    msg_Dbg( p_access, "fetch: url='%s'", p_sys->url);
++
++    p_access->pf_block = BlockFetch;
++    p_access->pf_control = Control;
++
++    return VLC_SUCCESS;
++}
++
++vlc_module_begin ()
++    set_shortname( N_("Fetch API") )
++    set_description( N_("Emscripten module to allow fetching remote resources") )
++    set_capability( "access", 0 )
++    //set_category( CAT_INPUT )
++    set_subcategory( SUBCAT_INPUT_ACCESS )
++    add_shortcut( "fetch", "https", "http" )
++    set_callbacks( EmFetchOpen, EmFetchClose )
++vlc_module_end()
diff --git a/vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch b/vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch
new file mode 100644
index 0000000..a75c368
--- /dev/null
+++ b/vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch
@@ -0,0 +1,183 @@
+diff -Nuar vlc.original/modules/access/http/h1conn.c vlc/modules/access/http/h1conn.c
+--- vlc.original/modules/access/http/h1conn.c	2022-12-11 22:19:02.000000000 +0300
++++ vlc/modules/access/http/h1conn.c	2022-12-15 23:05:13.000000000 +0300
+@@ -387,7 +387,13 @@
+ 
+     for (const struct addrinfo *p = res; p != NULL; p = p->ai_next)
+     {
+-        vlc_tls_t *tcp = vlc_tls_SocketOpenAddrInfo(p, idempotent);
++        vlc_tls_t *tcp = vlc_tls_SocketOpenAddrInfo(p,
++#ifdef __EMSCRIPTEN__
++              false
++#else
++              idempotent
++#endif
++              );
+         if (tcp == NULL)
+         {
+             vlc_http_err(ctx, "socket error: %s", vlc_strerror_c(errno));
+@@ -418,7 +424,9 @@
+ 
+         vlc_http_conn_release(conn);
+ 
++#ifndef __EMSCRIPTEN__
+         if (!idempotent)
++#endif
+             break; /* If the request is nonidempotent, it cannot be resent. */
+     }
+ 
+diff -Nuar vlc.original/modules/access/http/resource.c vlc/modules/access/http/resource.c
+--- vlc.original/modules/access/http/resource.c	2022-12-11 22:19:02.000000000 +0300
++++ vlc/modules/access/http/resource.c	2022-12-15 20:16:28.000000000 +0300
+@@ -182,7 +182,11 @@
+     }
+ 
+     if (!vlc_ascii_strcasecmp(url.psz_protocol, "https"))
++#ifdef __EMSCRIPTEN__
++        secure = false;
++#else
+         secure = true;
++#endif
+     else if (!vlc_ascii_strcasecmp(url.psz_protocol, "http"))
+         secure = false;
+     else
+diff -Nuar vlc.original/src/network/stream.c vlc/src/network/stream.c
+--- vlc.original/src/network/stream.c	2022-12-11 22:19:03.000000000 +0300
++++ vlc/src/network/stream.c	2022-12-19 17:19:03.000000000 +0300
+@@ -183,6 +183,9 @@
+                                   unsigned count)
+ {
+     vlc_tls_socket_t *sock = (struct vlc_tls_socket *)tls;
++#ifdef __EMSCRIPTEN__
++    return recv(sock->fd, iov->iov_base, iov->iov_len, 0);
++#else
+     struct msghdr msg =
+     {
+         .msg_iov = iov,
+@@ -190,6 +193,7 @@
+     };
+ 
+     return recvmsg(sock->fd, &msg, 0);
++#endif
+ }
+ 
+ static ssize_t vlc_tls_SocketWrite(vlc_tls_t *tls, const struct iovec *iov,
+diff -Nuar vlc.original/src/posix/filesystem.c vlc/src/posix/filesystem.c
+--- vlc.original/src/posix/filesystem.c	2022-12-11 22:20:21.000000000 +0300
++++ vlc/src/posix/filesystem.c	2022-12-15 22:00:46.000000000 +0300
+@@ -48,7 +48,9 @@
+ #if !defined(HAVE_ACCEPT4)
+ static inline void vlc_cloexec(int fd)
+ {
++#ifndef __EMSCRIPTEN__
+     fcntl(fd, F_SETFD, FD_CLOEXEC | fcntl(fd, F_GETFD));
++#endif
+ }
+ #endif
+ #if !defined(MSG_NOSIGNAL) && defined(SO_NOSIGPIPE)
+@@ -112,6 +114,9 @@
+     if (unlikely(ret != 0) && unlikely(errno == EINTR))
+         errno = EINPROGRESS;
+ #endif
++#ifdef __EMSCRIPTEN__
++    ret = 0;
++#endif
+     assert(ret == 0 || errno != EBADF); /* something is corrupt? */
+     return ret;
+ }
+@@ -256,8 +261,10 @@
+ {
+     vlc_cloexec(fd);
+ 
++#ifndef __EMSCRIPTEN__
+     if (nonblock)
+         fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
++#endif
+ 
+ #ifdef SO_NOSIGPIPE
+     setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){ 1 }, sizeof (int));
+@@ -267,7 +274,7 @@
+ 
+ int vlc_socket (int pf, int type, int proto, bool nonblock)
+ {
+-#ifdef SOCK_CLOEXEC
++#if defined(SOCK_CLOEXEC) && !defined(__EMSCRIPTEN__)
+     if (nonblock)
+         type |= SOCK_NONBLOCK;
+ 
+@@ -286,7 +293,7 @@
+ 
+ int vlc_socketpair(int pf, int type, int proto, int fds[2], bool nonblock)
+ {
+-#ifdef SOCK_CLOEXEC
++#if defined(SOCK_CLOEXEC) && !defined(__EMSCRIPTEN__)
+     if (nonblock)
+         type |= SOCK_NONBLOCK;
+ 
+@@ -313,7 +320,7 @@
+ 
+ int vlc_accept (int lfd, struct sockaddr *addr, socklen_t *alen, bool nonblock)
+ {
+-#ifdef HAVE_ACCEPT4
++#if defined(HAVE_ACCEPT4) && !defined(__EMSCRIPTEN__)
+     int flags = SOCK_CLOEXEC;
+     if (nonblock)
+         flags |= SOCK_NONBLOCK;
+@@ -333,12 +340,19 @@
+ 
+ ssize_t vlc_send(int fd, const void *buf, size_t len, int flags)
+ {
+-    return vlc_sendto(fd, buf, len, flags, NULL, 0);
++#ifdef __EMSCRIPTEN__
++   return send(fd, buf, len, flags | MSG_NOSIGNAL);
++#else
++   return vlc_sendto(fd, buf, len, flags, NULL, 0);
++#endif
+ }
+ 
+ ssize_t vlc_sendto(int fd, const void *buf, size_t len, int flags,
+                    const struct sockaddr *dst, socklen_t dstlen)
+ {
++#ifdef __EMSCRIPTEN__
++    return vlc_send(fd, buf, len, flags);
++#else
+     struct iovec iov = {
+         .iov_base = (void *)buf,
+         .iov_len = len,
+@@ -351,9 +365,14 @@
+     };
+ 
+     return vlc_sendmsg(fd, &msg, flags);
++#endif
+ }
+ 
+ ssize_t vlc_sendmsg(int fd, const struct msghdr *msg, int flags)
+ {
++#ifdef __EMSCRIPTEN__
++    return vlc_send(fd, msg->msg_iov->iov_base, msg->msg_iov->iov_len, flags);
++#else
+     return sendmsg(fd, msg, flags | MSG_NOSIGNAL);
++#endif
+ }
+diff -Nuar vlc.original/src/posix/getaddrinfo.c vlc/src/posix/getaddrinfo.c
+--- vlc.original/src/posix/getaddrinfo.c	2022-12-11 22:20:21.000000000 +0300
++++ vlc/src/posix/getaddrinfo.c	2022-12-15 21:46:22.000000000 +0300
+@@ -73,6 +73,10 @@
+         req.service = portbuf;
+     }
+ 
++#ifdef __EMSCRIPTEN__
++    req.error = EAI_SYSTEM;
++    req.error = getaddrinfo(req.name, req.service, req.hints, req.result);
++#else
+     vlc_sem_init(&req.done, 0);
+ 
+     if (vlc_clone(&th, vlc_gai_thread, &req, VLC_THREAD_PRIORITY_LOW))
+@@ -82,6 +86,6 @@
+ 
+     vlc_cancel(th);
+     vlc_join(th, NULL);
+-
++#endif
+     return req.error;
+ }
-- 
2.24.3 (Apple Git-128)



More information about the vlc-devel mailing list