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

Call Emit inside a c++ Lambda fucnction #887

Closed
shadow111 opened this issue Jan 23, 2021 · 5 comments
Closed

Call Emit inside a c++ Lambda fucnction #887

shadow111 opened this issue Jan 23, 2021 · 5 comments
Labels

Comments

@shadow111
Copy link

Hello This actually not an issue but i'm seeking some recommendation
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

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

But i just get

Start Recording …

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.

@kidneysolo
Copy link
Contributor

kidneysolo commented Jan 28, 2021

Hi @shadow111

If the lambda passed to framePool.FrameArrived is run on a different thread you cannot directly call javascript functions in it.

I recommend to take a look at the ThreadSafeFunction API which should suit your use case.

@forthegithub

This comment has been minimized.

@shadow111

This comment has been minimized.

@addaleax
Copy link
Member

I’ve hidden the off-topic comments here as off-topic, if you have another problem please open another issue (in e.g. https://github.com/nodejs/help/issues/). Also, pinging a bunch of people for no good reason is not cool and is not going to get your problem solved any faster.

@github-actions
Copy link
Contributor

github-actions bot commented May 2, 2021

This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants