Commit 0fd03d10 authored by Linshizhi's avatar Linshizhi

Add getVideo to MediaCodex.MP4.

parent 095f896e
...@@ -624,6 +624,7 @@ namespace internal { ...@@ -624,6 +624,7 @@ namespace internal {
CPP(InitEncodeContext) \ CPP(InitEncodeContext) \
CPP(Encode) \ CPP(Encode) \
CPP(Close) \ CPP(Close) \
CPP(GetVideo) \
\ \
/* Web snapshots */ \ /* Web snapshots */ \
CPP(WebSnapshotSerialize) \ CPP(WebSnapshotSerialize) \
......
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <cstdio>
#include <fstream>
#include "builtins-encoder.h"
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "extensions/encoder/src/encoder.h" #include "extensions/encoder/src/encoder.h"
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
...@@ -17,24 +20,22 @@ LAIPIC_ENCODER::Encoder *enc; ...@@ -17,24 +20,22 @@ LAIPIC_ENCODER::Encoder *enc;
BUILTIN(InitEncodeContext) { BUILTIN(InitEncodeContext) {
HandleScope scope(isolate); HandleScope scope(isolate);
// Output path
Handle<Object> path = args.atOrUndefined(isolate, 1);
// Width // Width
Handle<Object> width = args.atOrUndefined(isolate, 2); Handle<Object> width = args.atOrUndefined(isolate, 1);
// Height // Height
Handle<Object> height = args.atOrUndefined(isolate, 3); Handle<Object> height = args.atOrUndefined(isolate, 2);
// Bitrate // Bitrate
Handle<Object> bitrate = args.atOrUndefined(isolate, 4); Handle<Object> bitrate = args.atOrUndefined(isolate, 3);
// Framerate // Framerate
Handle<Object> framerate = args.atOrUndefined(isolate, 5); Handle<Object> framerate = args.atOrUndefined(isolate, 4);
// Libav Path, Optional // Libav Path, Optional
Handle<Object> libpath = args.atOrUndefined(isolate, 6); Handle<Object> libpath = args.atOrUndefined(isolate, 5);
// Maybe an Encoder already exists. // Maybe an Encoder already exists.
if (inited) return *isolate->factory()->ToBoolean(true); if (inited) return *isolate->factory()->ToBoolean(true);
// Argument check // Argument check
if (!path->IsString() || !width->IsNumber() || !height->IsNumber() || if (!width->IsNumber() || !height->IsNumber() ||
!bitrate->IsNumber() || !framerate->IsNumber()) { !bitrate->IsNumber() || !framerate->IsNumber()) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
...@@ -52,12 +53,11 @@ BUILTIN(InitEncodeContext) { ...@@ -52,12 +53,11 @@ BUILTIN(InitEncodeContext) {
libpath_cppstr = libpath_str->ToCString().get(); libpath_cppstr = libpath_str->ToCString().get();
} }
// Convert to C/C++ type // Output mp4 file path
Handle<String> path_str; std::string outpath = std::tmpnam(nullptr);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, path_str, outpath += ".mp4";
Object::ToString(isolate, path));
std::string outpath = { path_str->ToCString().get() };
// Convert to C/C++ type
uint32_t width_int, height_int, bitrate_int, framerate_int; uint32_t width_int, height_int, bitrate_int, framerate_int;
width->ToUint32(&width_int); width->ToUint32(&width_int);
...@@ -133,5 +133,34 @@ BUILTIN(Close) { ...@@ -133,5 +133,34 @@ BUILTIN(Close) {
return *isolate->factory()->ToBoolean(true); return *isolate->factory()->ToBoolean(true);
} }
// Return Values;
// Success: An Uint8Array contains video info.
// Failed: Undefined.
BUILTIN(GetVideo) {
HandleScope scope(isolate);
if (!inited) {
return ReadOnlyRoots(isolate).undefined_value();
}
// Open video file so able to determine the size of file
std::ifstream videoFile {
enc->getOutputPath(), std::ifstream::binary | std::ifstream::ate };
size_t fileLength = videoFile.tellg();
Handle<JSTypedArray> videoContent =
EncodeNewJSTypedArray(isolate, fileLength);
videoFile.seekg(0);
// Get internal buffer of JSTypedArray
std::shared_ptr<BackingStore> store = videoContent->GetBuffer()->GetBackingStore();
char *buffer = reinterpret_cast<char*>(store->buffer_start());
// Fill file content into TypedArray
videoFile.read(buffer, fileLength);
return *videoContent;
}
} // internal } // internal
} // v8 } // v8
...@@ -5,80 +5,86 @@ ...@@ -5,80 +5,86 @@
#include "src/builtins/builtins-utils-inl.h" #include "src/builtins/builtins-utils-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
//提取字段 //提取字段
inline Handle<Object> EncodeGetProperty(v8::internal::Isolate* isolate, v8::internal::Handle<v8::internal::Object> object, const char* name) { inline Handle<Object> EncodeGetProperty(v8::internal::Isolate* isolate, v8::internal::Handle<v8::internal::Object> object, const char* name) {
Handle<String> h_name = isolate->factory()->InternalizeUtf8String(name); Handle<String> h_name = isolate->factory()->InternalizeUtf8String(name);
Handle<Object> result; Handle<Object> result;
bool succ = Object::GetProperty(isolate, object, h_name).ToHandle(&result); bool succ = Object::GetProperty(isolate, object, h_name).ToHandle(&result);
if (result.is_null() || !succ) { if (result.is_null() || !succ) {
return isolate->factory()->undefined_value(); return isolate->factory()->undefined_value();
} }
return result; return result;
} }
//对象转cstring //对象转cstring
inline std::unique_ptr<char[]> EncodeToCString(v8::internal::Isolate* isolate, v8::internal::Handle<v8::internal::Object> object) { inline std::unique_ptr<char[]> EncodeToCString(v8::internal::Isolate* isolate, v8::internal::Handle<v8::internal::Object> object) {
if (!object->IsString()) return std::unique_ptr<char[]>(nullptr); if (!object->IsString()) return std::unique_ptr<char[]>(nullptr);
Handle<String> string = Handle<String>::cast(object); Handle<String> string = Handle<String>::cast(object);
return string->ToCString(); return string->ToCString();
} }
//TypedArray 或 ArrayBuffer 对象转指针 //TypedArray 或 ArrayBuffer 对象转指针
inline std::tuple<uint8_t*, size_t> EncodeToBuffer(v8::internal::Isolate* isolate, v8::internal::Handle<v8::internal::Object> object) { inline std::tuple<uint8_t*, size_t> EncodeToBuffer(v8::internal::Isolate* isolate, v8::internal::Handle<v8::internal::Object> object) {
Handle<JSArrayBuffer> jsab; Handle<JSArrayBuffer> jsab;
//size_t size; //size_t size;
if (object->IsJSTypedArray()) { if (object->IsJSTypedArray()) {
auto jsta = JSTypedArray::Validate(isolate, object, "EncodeToBuffer").ToHandleChecked(); auto jsta = JSTypedArray::Validate(isolate, object, "EncodeToBuffer").ToHandleChecked();
jsab = jsta->GetBuffer(); jsab = jsta->GetBuffer();
//size = jsta->GetByteLength(); //size = jsta->GetByteLength();
} }
else if (object->IsJSArrayBuffer()) { else if (object->IsJSArrayBuffer()) {
jsab = Handle<JSArrayBuffer>::cast(object); jsab = Handle<JSArrayBuffer>::cast(object);
if (jsab->IsNullOrUndefined()) { if (jsab->IsNullOrUndefined()) {
isolate->Throw(*isolate->factory()->NewTypeError( isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kInvalidArrayBufferLength)); MessageTemplate::kInvalidArrayBufferLength));
}
}
if (jsab->IsNullOrUndefined()) return std::tuple<uint8_t*, size_t>(nullptr, 0);
std::shared_ptr<v8::internal::BackingStore> store = jsab->GetBackingStore();
return std::tuple<uint8_t*, size_t>((uint8_t*)store->buffer_start(), store->byte_length());
} }
}
if (jsab->IsNullOrUndefined()) return std::tuple<uint8_t*, size_t>(nullptr, 0);
std::shared_ptr<v8::internal::BackingStore> store = jsab->GetBackingStore();
return std::tuple<uint8_t*, size_t>((uint8_t*)store->buffer_start(), store->byte_length());
}
inline Handle<JSObject> EncodeNewJSObject(v8::internal::Isolate* isolate) { inline Handle<JSObject> EncodeNewJSObject(v8::internal::Isolate* isolate) {
return isolate->factory()->NewJSObject(isolate->object_function(), AllocationType::kOld); return isolate->factory()->NewJSObject(isolate->object_function(), AllocationType::kOld);
} }
inline void EncodeAddPropertyObject(Isolate* isolate, Handle<JSObject> object, const char* key, Handle<Object> value) { inline void EncodeAddPropertyObject(Isolate* isolate, Handle<JSObject> object, const char* key, Handle<Object> value) {
JSObject::AddProperty(isolate, object, key, value, PropertyAttributes::NONE); JSObject::AddProperty(isolate, object, key, value, PropertyAttributes::NONE);
} }
inline void EncodeAddPropertyNumber(Isolate* isolate, Handle<JSObject> object, const char* key, double value) { inline void EncodeAddPropertyNumber(Isolate* isolate, Handle<JSObject> object, const char* key, double value) {
Handle<Object> valueObj = isolate->factory()->NewNumber(value); Handle<Object> valueObj = isolate->factory()->NewNumber(value);
JSObject::AddProperty(isolate, object, key, valueObj, PropertyAttributes::NONE); JSObject::AddProperty(isolate, object, key, valueObj, PropertyAttributes::NONE);
} }
inline void EncodeAddPropertyString(Isolate* isolate, Handle<JSObject> object, const char* key, const char* value) { inline void EncodeAddPropertyString(Isolate* isolate, Handle<JSObject> object, const char* key, const char* value) {
Handle<String> strObj = isolate->factory()->InternalizeUtf8String(value); Handle<String> strObj = isolate->factory()->InternalizeUtf8String(value);
//字段设置为 PropertyAttributes::DontEnum 时,无法通过键值对遍历 Object.keys(retObj) //字段设置为 PropertyAttributes::DontEnum 时,无法通过键值对遍历 Object.keys(retObj)
JSObject::AddProperty(isolate, object, key, strObj, PropertyAttributes::NONE); JSObject::AddProperty(isolate, object, key, strObj, PropertyAttributes::NONE);
} }
inline Handle<JSArrayBuffer> EncodeNewJSArrayBuffer(v8::internal::Isolate* isolate, size_t size) { inline Handle<JSArrayBuffer> EncodeNewJSArrayBuffer(v8::internal::Isolate* isolate, size_t size) {
MaybeHandle<JSArrayBuffer> arrbuffOjb = MaybeHandle<JSArrayBuffer> arrbuffOjb =
isolate->factory()->NewJSArrayBufferAndBackingStore( isolate->factory()->NewJSArrayBufferAndBackingStore(
size, InitializedFlag::kZeroInitialized); size, InitializedFlag::kZeroInitialized);
Handle<JSArrayBuffer> result; Handle<JSArrayBuffer> result;
if (!arrbuffOjb.ToHandle(&result)) { if (!arrbuffOjb.ToHandle(&result)) {
isolate->Throw(*isolate->factory()->NewTypeError( isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kInvalidArrayBufferLength)); MessageTemplate::kInvalidArrayBufferLength));
return result; return result;
} }
return result; return result;
} }
inline Handle<JSTypedArray> EncodeNewJSTypedArray(v8::internal::Isolate* isolate, size_t size) {
Handle<JSArrayBuffer> buffer = EncodeNewJSArrayBuffer(isolate, size);
return isolate->factory()->NewJSTypedArray(
kExternalInt8Array, buffer, 0, size);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
#endif // V8_BUILTINS_BUILTINS_ENCODER_H_ #endif // V8_BUILTINS_BUILTINS_ENCODER_H_
...@@ -2795,11 +2795,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, ...@@ -2795,11 +2795,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
factory->NewJSObject(isolate_->object_function(), AllocationType::kOld); factory->NewJSObject(isolate_->object_function(), AllocationType::kOld);
JSObject::AddProperty(isolate_, media_codex, "Mp4", mp4, DONT_ENUM); JSObject::AddProperty(isolate_, media_codex, "Mp4", mp4, DONT_ENUM);
SimpleInstallFunction(isolate_, mp4, "init", SimpleInstallFunction(isolate_, mp4, "init",
Builtin::kInitEncodeContext, 6, true); Builtin::kInitEncodeContext, 5, true);
SimpleInstallFunction(isolate_, mp4, "encode", SimpleInstallFunction(isolate_, mp4, "encode",
Builtin::kEncode, 1, true); Builtin::kEncode, 1, true);
SimpleInstallFunction(isolate_, mp4, "close", SimpleInstallFunction(isolate_, mp4, "close",
Builtin::kClose, 0, true); Builtin::kClose, 0, true);
SimpleInstallFunction(isolate_, mp4, "getVideo",
Builtin::kGetVideo, 0, true);
InstallToStringTag(isolate_, media_codex, "MediaCodex"); InstallToStringTag(isolate_, media_codex, "MediaCodex");
} }
......
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