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

add wasm build support #3577

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ testbin/test_vd_rc.264
testbin/test_vd_rc.yuv
testbin/test.264
testbin/test.yuv
testbin/Static.264
testbin/Static.yuv

# iOS output files
codec/build/iOS/common/build/
Expand All @@ -57,3 +59,11 @@ codec/build/iOS/dec/welsdec/build/
# editor files
*~

#wasm
.vscode/*
*.html
*.js
*.wat
*.wasm
*.data

6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ OS=$(shell uname | tr A-Z a-z | tr -d \\-0-9. | sed -E 's/^(net|open|free)bsd/bs
ARCH=$(shell uname -m)
LIBPREFIX=lib
LIBSUFFIX=a
# EMFS = nodefs | memfs
EMFS=
CCAS=$(CC)
CXX_O=-o $@
CXX_LINK_O=-o $@
Expand Down Expand Up @@ -170,7 +172,7 @@ clean:
ifeq (android,$(OS))
clean: clean_Android
endif
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(OBJS:.$(OBJ)=.obj) $(LIBRARIES) $(BINARIES) *.lib *.a *.dylib *.dll *.so *.so.* *.exe *.pdb *.exp *.pc *.res *.map $(SRC_PATH)codec/common/inc/version_gen.h
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(OBJS:.$(OBJ)=.obj) $(LIBRARIES) $(BINARIES) *.lib *.a *.js *.html *.wasm *.wat *.data *.dylib *.dll *.so *.so.* *.exe *.pdb *.exp *.pc *.res *.map $(SRC_PATH)codec/common/inc/version_gen.h

gmp-bootstrap:
if [ ! -d gmp-api ] ; then git clone https://github.com/mozilla/gmp-api gmp-api ; fi
Expand Down Expand Up @@ -382,4 +384,4 @@ OBJDIRS = $(sort $(dir $(OBJS)))
$(OBJDIRS):
$(QUIET)mkdir -p $@

$(OBJS): | $(OBJDIRS)
$(OBJS): | $(OBJDIRS)
11 changes: 10 additions & 1 deletion build/mktargets.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,16 @@ def find_sources():
if args.binary is not None:
f.write("%s$(EXEEXT): $(%s_OBJS) $(%s_DEPS)\n"%(args.binary, PREFIX, PREFIX))
f.write("\t$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(%s_OBJS) $(%s_LDFLAGS) $(LDFLAGS)\n\n"%(PREFIX, PREFIX))
# for wasm build
f.write("%s.html: $(%s_OBJS) $(%s_DEPS)\n"%(args.binary, PREFIX, PREFIX))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't you avoid duplicating all this by just setting EXEEXT = .html?

f.write("\t$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(%s_OBJS) $(%s_LDFLAGS) $(LDFLAGS)\n\n"%(PREFIX, PREFIX))

f.write("ifeq ($(OS), wasm)\n")
f.write("binaries: %s.html\n"%args.binary)
f.write("BINARIES += %s.html\n"%args.binary)
f.write("else\n")
f.write("binaries: %s$(EXEEXT)\n"%args.binary)
f.write("BINARIES += %s$(EXEEXT)\n"%args.binary)
f.write("endif")

f.close()
f.close()
29 changes: 29 additions & 0 deletions build/platform-wasm.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
include $(SRC_PATH)build/arch.mk
SHAREDLIBSUFFIX = so
SHAREDLIBSUFFIXFULLVER=$(SHAREDLIBSUFFIX).$(FULL_VERSION)
SHAREDLIBSUFFIXMAJORVER=$(SHAREDLIBSUFFIX).$(SHAREDLIB_MAJORVERSION)
SHLDFLAGS = -Wl,-soname,$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXMAJORVER)
CFLAGS += -Wall -fno-strict-aliasing -fPIC -MMD -MP
# fix undifined symbol: __stack_chk_guard bug
# flags needed to build wasm
CFLAGS += -U_FORTIFY_SOURCE -pthread -DWASMSIMD -msimd128
CXXFLAGS += -U_FORTIFY_SOURCE -pthread -DWASMSIMD -msimd128
LDFLAGS += -U_FORTIFY_SOURCE -pthread -msimd128
ifeq ($(EMFS), nodefs)
CFLAGS += -DNODEFS
CXXFLAGS += -DNODEFS
LDFLAGS += -lnodefs.js
endif
ifeq ($(EMFS), memfs)
CFLAGS += -DMEMFS
CXXFLAGS += -DMEMFS
LDFLAGS += --preload-file ./testbin/workload
endif
ifeq ($(WASMDEBUG), True)
CFLAGS += -g2
CXXFLAGS += -g2
LDFLAGS += -g2
endif

STATIC_LDFLAGS += -lm
AR_OPTS = crD $@
47 changes: 44 additions & 3 deletions codec/console/dec/src/h264dec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
#if defined (ANDROID_NDK)
#include <android/log.h>
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

#include "codec_def.h"
#include "codec_app_def.h"
#include "codec_api.h"
Expand All @@ -60,6 +64,13 @@ float g_fDecFPS = 0.0;
int g_iDecodedFrameNum = 0;
#endif

#if defined(NODEFS)
#define CWD "/workload/"
#endif
#if defined(MEMFS)
#define CWD "testbin/workload/"
#endif

#if defined(ANDROID_NDK)
#define LOG_TAG "welsdec"
#define LOGI(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
Expand Down Expand Up @@ -256,7 +267,7 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
if (kpH264FileName) {
pH264File = fopen (kpH264FileName, "rb");
if (pH264File == NULL) {
fprintf (stderr, "Can not open h264 source file, check its legal path related please..\n");
fprintf (stderr, "Can not open h264 source file: %s, check its legal path related please..\n", kpH264FileName);
return;
}
fprintf (stderr, "H264 source file name: %s..\n", kpH264FileName);
Expand Down Expand Up @@ -505,14 +516,27 @@ int32_t main (int32_t iArgC, char* pArgV[]) {
sDecParam.sVideoProperty.size = sizeof (sDecParam.sVideoProperty);
sDecParam.eEcActiveIdc = ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE;

#if defined(NODEFS)
EM_ASM(
FS.mkdir('/workload');
FS.mount(NODEFS, { root: '.' }, '/workload');
);
#endif

if (iArgC < 2) {
printf ("usage 1: h264dec.exe welsdec.cfg\n");
printf ("usage 2: h264dec.exe welsdec.264 out.yuv\n");
printf ("usage 3: h264dec.exe welsdec.264\n");
return 1;
} else if (iArgC == 2) {
if (strstr (pArgV[1], ".cfg")) { // read config file //confirmed_safe_unsafe_usage
CReadConfig cReadCfg (pArgV[1]);
string cfgFilePath;
#if defined(NODEFS) || defined(MEMFS)
cfgFilePath = string(CWD) + string(pArgV[1]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the string(CWD) + needed?

Copy link
Author

@Yuhengwe1 Yuhengwe1 Oct 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the Emscripten File System

node.js environment for example, we map the main project dir to /workload in virtual filesystem.

After the mount we can run h264enc.js like: node h264enc.js testbin/xxx.cfg

The string(CWD) + add the path prefix. Without it we may need to run h264enc.js like node h264enc.js workload/testbin/xxx.cfg

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why map the main project dir to /workload instead of just the /?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I tried to mount host dir ./ to / in virtual FS for nods.js env, but this will cause error.

In browser env, packaging all the main will lead to longer file reading time.

#else
cfgFilePath = string(pArgV[1]);
#endif
CReadConfig cReadCfg (cfgFilePath.c_str());
string strTag[4];
string strReconFile ("");

Expand Down Expand Up @@ -554,14 +578,23 @@ int32_t main (int32_t iArgC, char* pArgV[]) {
}
} else if (strstr (pArgV[1],
".264")) { // no output dump yuv file, just try to render the decoded pictures //confirmed_safe_unsafe_usage
#if defined(NODEFS) || defined(MEMFS)
strInputFile = string(CWD) + string(pArgV[1]);
#else
strInputFile = pArgV[1];
#endif
sDecParam.uiTargetDqLayer = (uint8_t) - 1;
sDecParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
}
} else { //iArgC > 2
#if defined(NODEFS) || defined(MEMFS)
strInputFile = string(CWD) + string(pArgV[1]);
strOutputFile = string(CWD) + string(pArgV[2]);
#else
strInputFile = pArgV[1];
strOutputFile = pArgV[2];
#endif
sDecParam.uiTargetDqLayer = (uint8_t) - 1;
sDecParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
Expand All @@ -571,7 +604,11 @@ int32_t main (int32_t iArgC, char* pArgV[]) {

if (!strcmp (cmd, "-options")) {
if (i + 1 < iArgC)
#if defined(NODEFS) || defined(MEMFS)
strOptionFile = string(CWD) + string(pArgV[++i]);
#else
strOptionFile = pArgV[++i];
#endif
else {
printf ("options file not specified.\n");
return 1;
Expand All @@ -585,7 +622,11 @@ int32_t main (int32_t iArgC, char* pArgV[]) {
}
} else if (!strcmp (cmd, "-length")) {
if (i + 1 < iArgC)
#if defined(NODEFS) || defined(MEMFS)
strLengthFile = string(CWD) + string(pArgV[++i]);
#else
strLengthFile = pArgV[++i];
#endif
else {
printf ("lenght file not specified.\n");
return 1;
Expand Down Expand Up @@ -655,4 +696,4 @@ int32_t main (int32_t iArgC, char* pArgV[]) {
}

return 0;
}
}
8 changes: 8 additions & 0 deletions codec/console/dec/targets.mk
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,13 @@ $(H264DEC_SRCDIR)/%.$(OBJ): $(H264DEC_SRCDIR)/%.cpp
h264dec$(EXEEXT): $(H264DEC_OBJS) $(H264DEC_DEPS)
$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(H264DEC_OBJS) $(H264DEC_LDFLAGS) $(LDFLAGS)

h264dec.html: $(H264DEC_OBJS) $(H264DEC_DEPS)
$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(H264DEC_OBJS) $(H264DEC_LDFLAGS) $(LDFLAGS)

ifeq ($(OS), wasm)
binaries: h264dec.html
BINARIES += h264dec.html
else
binaries: h264dec$(EXEEXT)
BINARIES += h264dec$(EXEEXT)
endif
56 changes: 49 additions & 7 deletions codec/console/enc/src/welsenc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#include <assert.h>
#include <signal.h>
#include <stdarg.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#if defined (ANDROID_NDK)
#include <android/log.h>
#endif
Expand Down Expand Up @@ -88,6 +91,13 @@ int g_iEncodedFrame = 0;
#endif
#endif /* _WIN32 */

#if defined(NODEFS)
#define CWD "/workload/"
#endif
#if defined(MEMFS)
#define CWD "testbin/workload/"
#endif

#if defined(__linux__) || defined(__unix__)
#define _FILE_OFFSET_BITS 64
#endif
Expand Down Expand Up @@ -238,10 +248,22 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
} else if (strTag[0].compare ("SourceHeight") == 0) {
pSrcPic->iPicHeight = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("InputFile") == 0) {
string inputFile;
#if defined(NODEFS) || defined(MEMFS)
inputFile = string(CWD) + strTag[1];
#else
inputFile = strTag[1];
#endif
if (strTag[1].length() > 0)
sFileSet.strSeqFile = strTag[1];
sFileSet.strSeqFile = inputFile;
} else if (strTag[0].compare ("OutputFile") == 0) {
sFileSet.strBsFile = strTag[1];
string outputFile;
#if defined(NODEFS) || defined(MEMFS)
outputFile = string(CWD) + strTag[1];
#else
outputFile = strTag[1];
#endif
sFileSet.strBsFile = outputFile;
} else if (strTag[0].compare ("MaxFrameRate") == 0) {
pSvcParam.fMaxFrameRate = (float)atof (strTag[1].c_str());
} else if (strTag[0].compare ("FramesToBeEncoded") == 0) {
Expand Down Expand Up @@ -356,10 +378,17 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
break;
}
} else if (strTag[0].compare ("LayerCfg") == 0) {
if (strTag[1].length() > 0)
sFileSet.strLayerCfgFile[iLayerCount] = strTag[1];
if (strTag[1].length() > 0) {
string cfgFilePath;
#if defined(NODEFS) || defined(MEMFS)
cfgFilePath = string(CWD) + strTag[1];
#else
cfgFilePath = strTag[1];
#endif
sFileSet.strLayerCfgFile[iLayerCount] = cfgFilePath;
++iLayerCount;
}
// pSvcParam.sDependencyLayers[iLayerCount].uiDependencyId = iLayerCount;
++ iLayerCount;
} else if (strTag[0].compare ("PrefixNALAddingCtrl") == 0) {
int ctrl_flag = atoi (strTag[1].c_str());
if (ctrl_flag > 1)
Expand Down Expand Up @@ -801,7 +830,13 @@ int ProcessEncoding (ISVCEncoder* pPtrEnc, int argc, char** argv, bool bConfigFi
// if configure file exit, reading configure file firstly
if (bConfigFile) {
iParsedNum = 2;
cRdCfg.Openf (argv[1]);
string filePath;
#if defined(NODEFS) || defined(MEMFS)
filePath = string(CWD) + string(argv[1]);
#else
filePath = string(argv[1]);
#endif
cRdCfg.Openf (filePath.c_str());
if (!cRdCfg.ExistFile()) {
fprintf (stderr, "Specified file: %s not exist, maybe invalid path or parameter settting.\n",
cRdCfg.GetFileName().c_str());
Expand Down Expand Up @@ -1133,6 +1168,13 @@ int main (int argc, char** argv)
/* Control-C handler */
signal (SIGINT, SigIntHandler);

#if defined(NODEFS)
EM_ASM(
FS.mkdir('/workload');
FS.mount(NODEFS, { root: '.' }, '/workload');
);
#endif

iRet = CreateSVCEncHandle (&pSVCEncoder);
if (iRet) {
cout << "WelsCreateSVCEncoder() failed!!" << endl;
Expand Down Expand Up @@ -1167,4 +1209,4 @@ int main (int argc, char** argv)
DestroySVCEncHandle (pSVCEncoder);
PrintHelp();
return 1;
}
}
8 changes: 8 additions & 0 deletions codec/console/enc/targets.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,13 @@ $(H264ENC_SRCDIR)/%.$(OBJ): $(H264ENC_SRCDIR)/%.cpp
h264enc$(EXEEXT): $(H264ENC_OBJS) $(H264ENC_DEPS)
$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(H264ENC_OBJS) $(H264ENC_LDFLAGS) $(LDFLAGS)

h264enc.html: $(H264ENC_OBJS) $(H264ENC_DEPS)
$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(H264ENC_OBJS) $(H264ENC_LDFLAGS) $(LDFLAGS)

ifeq ($(OS), wasm)
binaries: h264enc.html
BINARIES += h264enc.html
else
binaries: h264enc$(EXEEXT)
BINARIES += h264enc$(EXEEXT)
endif
Loading