Commit 8065f496 authored by Linshizhi's avatar Linshizhi

Dynamic load encoder instead of static link.

parent eb27317c
[submodule "extensions/loadablemodule"]
path = extensions/loadablemodule
url = git@gitlab.laihua.com:linshizhi/loadablemodule.git
branch = main
[submodule "extensions/--force"] [submodule "extensions/--force"]
path = extensions/--force path = extensions/--force
url = git@gitlab.laihua.com:linshizhi/encoder.git url = git@gitlab.laihua.com:linshizhi/encoder.git
[submodule "extensions/encoder"]
path = extensions/encoder
url = git@gitlab.laihua.com:linshizhi/encoder.git
...@@ -4324,8 +4324,6 @@ v8_source_set("v8_base_without_compiler") { ...@@ -4324,8 +4324,6 @@ v8_source_set("v8_base_without_compiler") {
# Encoder # Encoder
"src/builtins/builtins-encoder.cc", "src/builtins/builtins-encoder.cc",
"extensions/encoder/src/encoder.cc",
"extensions/encoder/src/encoder_utils.cc",
"src/builtins/builtins-number.cc", "src/builtins/builtins-number.cc",
"src/builtins/builtins-object.cc", "src/builtins/builtins-object.cc",
......
Subproject commit c8b7e2f80ea73c915f70cb9aa1b7f8ae0af457a7
Subproject commit 7123dbdba735a1b43bfd586e2110e25bcdaab9ed
...@@ -3,24 +3,96 @@ ...@@ -3,24 +3,96 @@
#include <cstdio> #include <cstdio>
#include <fstream> #include <fstream>
#include <dlfcn.h>
#include "builtins-encoder.h" #include "builtins-encoder.h"
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "extensions/encoder/src/encoder.h"
#include "src/builtins/builtins.h"
#include "src/builtins/builtins-utils-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace { namespace {
bool inited = false; bool inited = false;
LAIPIC_ENCODER::Encoder *enc;
char *audioPath; char *audioPath;
void *loadedSyms;
void *encoder;
void* (*spawnEncoder)(const char *output, uint32_t width,
uint32_t height, uint32_t bitrate,
int fmt, int32_t framerate,
std::string encoderName);
void (*encoding)(void *encoder_, const uint8_t *buff, int length);
bool (*encoderFailed)(void *encoder_);
void (*closeEncoder)(void *encoder_);
const char* (*outputOfEncoder)(void *encoder_);
void* (*spawnMerger)(const char *output, const char *videoPath, const char *audioPath);
void (*merging)(void *merger_);
} }
BUILTIN(InitEncodeContext) { BUILTIN(InitEncodeContext) {
HandleScope scope(isolate); HandleScope scope(isolate);
// Dynamic load encoder
if (!loadedSyms) {
loadedSyms = dlopen("libencoder.so", RTLD_LAZY);
if (!loadedSyms) {
printf("Failed to load libencoder.so");
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
} else {
printf("libencoder.so loaded\n");
}
spawnEncoder = reinterpret_cast<decltype(spawnEncoder)>(dlsym(loadedSyms, "spawnEncoder"));
if (spawnEncoder == NULL) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
}
printf("spawnEncoder loaded\n");
encoding = reinterpret_cast<decltype(encoding)>(dlsym(loadedSyms, "encoding"));
if (encoding == NULL) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
}
printf("encoding loaded\n");
encoderFailed = reinterpret_cast<decltype(encoderFailed)>(dlsym(loadedSyms, "encoderFailed"));
if (encoderFailed == NULL) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
}
printf("encoderFailed loaded\n");
closeEncoder = reinterpret_cast<decltype(closeEncoder)>(dlsym(loadedSyms, "closeEncoder"));
if (closeEncoder == NULL) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
}
printf("closeEncoder loaded\n");
outputOfEncoder = reinterpret_cast<decltype(outputOfEncoder)>(dlsym(loadedSyms, "outputOfEncoder"));
if (outputOfEncoder == NULL) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
}
printf("outputOfEncoder loaded\n");
spawnMerger = reinterpret_cast<decltype(spawnMerger)>(dlsym(loadedSyms, "spawnMerger"));
if (spawnMerger == NULL) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
}
printf("spawnMerger loaded\n");
merging = reinterpret_cast<decltype(merging)>(dlsym(loadedSyms, "merging"));
if (merging == NULL) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewEvalError(MessageTemplate::kInvalidArgument));
}
printf("merging loaded\n");
}
// Width // Width
Handle<Object> width = args.atOrUndefined(isolate, 1); Handle<Object> width = args.atOrUndefined(isolate, 1);
// Height // Height
...@@ -68,21 +140,21 @@ BUILTIN(InitEncodeContext) { ...@@ -68,21 +140,21 @@ BUILTIN(InitEncodeContext) {
// First try to use h264_nvenc which may failed due // First try to use h264_nvenc which may failed due
// to host has no GPU. // to host has no GPU.
enc = new LAIPIC_ENCODER::Encoder { encoder = spawnEncoder(
libpath_cppstr, outpath, width_int, height_int, bitrate_int, outpath.c_str(), width_int, height_int, bitrate_int,
AV_PIX_FMT_YUV420P, 30, "h264_nvenc" }; 0, 30, "h264_nvenc");
if (!enc->isReady()) { if (!encoder) {
// Then try to use libx264 to working with CPU // Then try to use libx264 to working with CPU
// Release old encoder // Release old encoder
enc->close(); closeEncoder(encoder);
enc = new LAIPIC_ENCODER::Encoder { encoder = spawnEncoder(
libpath_cppstr, outpath, width_int, height_int, bitrate_int, outpath.c_str(), width_int, height_int, bitrate_int,
AV_PIX_FMT_YUV420P, 30, "libx264"}; 0, 30, "libx264");
if (!enc->isReady()) { if (!encoder) {
// Fail to initialize LAIPIC_ENCODER::Encoder. // Fail to initialize LAIPIC_ENCODER::Encoder.
// Probaly cause of invalid arguments. // Probaly cause of invalid arguments.
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
...@@ -102,7 +174,7 @@ BUILTIN(Encode) { ...@@ -102,7 +174,7 @@ BUILTIN(Encode) {
Handle<Object> frame = args.atOrUndefined(isolate, 1); Handle<Object> frame = args.atOrUndefined(isolate, 1);
if (frame->IsNull()) { if (frame->IsNull()) {
enc->encodeRGB(nullptr, 0); encoding(encoder, nullptr, 0);
return *isolate->factory()->ToBoolean(true); return *isolate->factory()->ToBoolean(true);
} }
...@@ -122,8 +194,8 @@ BUILTIN(Encode) { ...@@ -122,8 +194,8 @@ BUILTIN(Encode) {
return *isolate->factory()->ToBoolean(true); return *isolate->factory()->ToBoolean(true);
} }
enc->encodeRGB(buffer, bufferLen); encoding(encoder, buffer, bufferLen);
if (!enc->isReady()) { if (encoderFailed(encoder)) {
// Encoder fall into unready stat which // Encoder fall into unready stat which
// means there is something wrong happens during // means there is something wrong happens during
// during encodeing. // during encodeing.
...@@ -141,8 +213,8 @@ BUILTIN(Close) { ...@@ -141,8 +213,8 @@ BUILTIN(Close) {
return *isolate->factory()->ToBoolean(true); return *isolate->factory()->ToBoolean(true);
} }
enc->close(); closeEncoder(encoder);
enc = nullptr; encoder = nullptr;
inited = false; inited = false;
return *isolate->factory()->ToBoolean(true); return *isolate->factory()->ToBoolean(true);
...@@ -160,7 +232,7 @@ BUILTIN(GetVideo) { ...@@ -160,7 +232,7 @@ BUILTIN(GetVideo) {
// Open video file so able to determine the size of file // Open video file so able to determine the size of file
std::ifstream videoFile { std::ifstream videoFile {
enc->getOutputPath(), std::ifstream::binary | std::ifstream::ate }; outputOfEncoder(encoder), std::ifstream::binary | std::ifstream::ate };
size_t fileLength = videoFile.tellg(); size_t fileLength = videoFile.tellg();
Handle<JSTypedArray> videoContent = Handle<JSTypedArray> videoContent =
EncodeNewJSTypedArray(isolate, fileLength); EncodeNewJSTypedArray(isolate, fileLength);
...@@ -259,7 +331,7 @@ BUILTIN(MergeMP4) { ...@@ -259,7 +331,7 @@ BUILTIN(MergeMP4) {
if (!audioPath) { if (!audioPath) {
return *(isolate->factory()-> return *(isolate->factory()->
NewStringFromAsciiChecked(enc->getOutputPath().c_str())); NewStringFromAsciiChecked(outputOfEncoder(encoder)));
} }
Handle<Object> libpath = args.atOrUndefined(isolate, 1); Handle<Object> libpath = args.atOrUndefined(isolate, 1);
...@@ -287,15 +359,17 @@ BUILTIN(MergeMP4) { ...@@ -287,15 +359,17 @@ BUILTIN(MergeMP4) {
outpath_cppstr = outpath_str->ToCString().get(); outpath_cppstr = outpath_str->ToCString().get();
} }
LAIPIC_ENCODER::AVMerger merger(libpath_cppstr, outpath_cppstr, enc->getOutputPath(), audioPath); void *merger = spawnMerger(
merger.merge(); outpath_cppstr.c_str(),
outputOfEncoder(encoder), audioPath);
merging(merger);
std::remove(audioPath); std::remove(audioPath);
Handle<String> mergepath = isolate->factory()->NewStringFromAsciiChecked(outpath_cppstr.c_str()); Handle<String> mergepath = isolate->factory()->NewStringFromAsciiChecked(outpath_cppstr.c_str());
free(audioPath); free(audioPath);
audioPath = nullptr; audioPath = nullptr;
std::remove(enc->getOutputPath().c_str()); std::remove(outputOfEncoder(encoder));
return *mergepath; return *mergepath;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment