NAPI Call Emit inside a c++ Lambda fucnction

450 Views Asked by At

I'm working on a N-API addon to capture video frame using windows graphic capture API , extract frame bytes and send it back to JavaScript. I have tried the event emitter but I can't get the data.

Here is my C++ code:

#include <napi.h>
// my other include

Napi::Value startCapture(const Napi::CallbackInfo &info){
    Napi::Env env = info.Env();
    Napi::Function emit = info[0].As<Napi::Function>();
    emit.Call({Napi::String::New(env, "start")});
    auto framePool = winrt::Direct3D11CaptureFramePool::Create(
    device, //d3d device
    winrt::DirectXPixelFormat::B8G8R8A8UIntNormalized,
    2,
    itemSize);
    // capture session
    auto session = framePool.CreateCaptureSession(item);

    // Lambda Function 
    framePool.FrameArrived([session, d3dDevice, d3dContext, &emit, &env](auto &framePool, auto &) {
        auto frame = framePool.TryGetNextFrame();
        auto frameTexture = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
        // Extraction the byte and so on ...
        emit.Call({Napi::String::New(env, "data"), Napi::String::New(env, "data ...")});
    }
    
    session.StartCapture();
    emit.Call({Napi::String::New(env, "end")});
    return Napi::String::New(env, "OK");
}

here my JavaScript code calling the start capture function

<!-- language-all: js -->
const EventEmitter = require('events').EventEmitter
const addon = require('./build/myaddon.node')
const emitter = new EventEmitter()

emitter.on('start', () => {
    console.log('Start Recording ...')
})
emitter.on('data', (evt) => {
    console.log(evt);
})

emitter.on('end', () => {
    console.log('Stop Recording ...')
})

addon.startCapture(emitter.emit.bind(emitter))

Normally my output should be an infinite loop of data messages until I stop it

Start Recording … data data . . . data

After looking to the lambda function framePool.FrameArrived it seems that it's running on a different thread than the startCapture function if I understand the lambda function concept correctly, I just wanna to found a way on how I can stream those messages to JavaScript using event Emitter or any other recommendation is well welcoming.

1

There are 1 best solutions below

0
On
//instead of
Napi::Env env = info.Env();
Napi::Function emit = info[0].As<Napi::Function>();    
emit.Call({Napi::String::New(env, "data"), Napi::String::New(env, "data ...")});

//try
Napi::Env env = info.Env();
Napi::Function fn = info[0].As<Napi::Function>();
emit = Persistent(fn);
emit.SuppressDestruct();
emit.Value().Call({Napi::String::New(env, "data"), Napi::String::New(env, "data ...")});