30#include <freerdp/config.h>
32#include <emscripten.h>
33#include <emscripten/proxying.h>
34#include <emscripten/threading.h>
36#include <winpr/assert.h>
37#include <freerdp/codec/color.h>
39#include "av1_webcodecs.h"
57extern int av1_wc_js_available(
void);
58extern int av1_wc_js_open(
void);
59extern void av1_wc_js_close(
int handle);
60extern void av1_wc_js_decode(
void* ctx,
int handle,
const BYTE* src, UINT32 size, BYTE* dst,
61 const char* formatName, UINT32 stride, UINT32 width, UINT32 height,
62 int key,
int profile,
int* rc);
64EMSCRIPTEN_KEEPALIVE
void freerdp_av1_wc_finish(em_proxying_ctx* ctx)
66 emscripten_proxy_finish(ctx);
69static void main_available(
void* arg)
71 *(
int*)arg = av1_wc_js_available();
74static void main_open(
void* arg)
76 *(
int*)arg = av1_wc_js_open();
79static void main_close(
void* arg)
81 av1_wc_js_close(*(
int*)arg);
84static void main_decode(em_proxying_ctx* ctx,
void* arg)
86 av1_wc_job* job = arg;
89 av1_wc_js_decode(ctx, job->handle, job->src, job->size, job->dst, job->format, job->stride,
90 job->width, job->height, job->key, job->profile, &job->rc);
93static BOOL on_main(
void (*fn)(
void*),
void* arg)
97 if (emscripten_is_main_browser_thread())
102 return emscripten_proxy_sync(emscripten_proxy_get_system_queue(),
103 emscripten_main_runtime_thread_id(), fn, arg) == 1;
109 if (!on_main(main_available, &available) || !available)
112 if (!on_main(main_open, &handle))
117void av1_wc_close(
int handle)
120 (void)on_main(main_close, &handle);
125static int sequence_header_profile(
const BYTE* p, UINT32 size)
130 const BYTE header = p[pos];
131 const int type = (header >> 3) & 0x0f;
132 const int has_extension = (header >> 2) & 1;
133 const int has_size = (header >> 1) & 1;
134 pos += 1 + (UINT32)has_extension;
136 return (type == 1 && pos < size) ? (p[pos] >> 5) : -1;
138 for (
int i = 0; i < 8 && pos < size; i++)
140 const BYTE b = p[pos++];
141 len |= (UINT64)(b & 0x7f) << (7 * i);
146 return (pos < size) ? (p[pos] >> 5) : -1;
147 if (len > size - pos)
154static const char* copy_format(DWORD DstFormat)
158 case PIXEL_FORMAT_BGRA32:
160 case PIXEL_FORMAT_BGRX32:
162 case PIXEL_FORMAT_RGBA32:
164 case PIXEL_FORMAT_RGBX32:
171INT32 av1_wc_decode(
int handle,
const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData,
172 DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight)
174 const char* format = copy_format(DstFormat);
176 return AV1_WC_UNSUPPORTED;
177 if (emscripten_is_main_browser_thread())
180 const int profile = sequence_header_profile(pSrcData, SrcSize);
181 av1_wc_job job = { .handle = handle,
188 .height = nDstHeight,
192 if (emscripten_proxy_sync_with_ctx(emscripten_proxy_get_system_queue(),
193 emscripten_main_runtime_thread_id(), main_decode, &job) != 1)