Results 1 to 8 of 8

Thread: NDIlib_recv_create_v3() Crash unless passed nullptr

  1. #1
    Registered User
    Join Date
    Nov 2019
    Location
    Canada
    Posts
    11

    NDIlib_recv_create_v3() Crash unless passed nullptr

    Hello guys,

    I'm using NDI SDK 4 with GCC 7.3.0 (64 bit) and 5.3.0 (32 bit).

    When trying to create a receiver using NDIlib_recv_create_v3() as shown below, the function crashes:

    //Receiver setup
    receiverSettings.color_format = NDIlib_recv_color_format_fastest;
    receiverSettings.p_ndi_recv_name = "TEST RECEIVER";
    receiverSettings.source_to_connect_to = nullptr;

    video = NDIlib_recv_create_v3(&receiverSettings);

    I get the following in my stack:

    Processing.NDI.Lib.x64!NDIlib_recv_create_v3
    Processing.NDI.Lib.x64!NDIlib_version
    Processing.NDI.Lib.x64!NDIlib_util_P216_to_V210

    If I use a NDIlib_recv_create_t instance with NDIlib_recv_create_v2() things seem to work ok (the only downside being that p_ndi_recv_name is not available).

    Worth mentioning I had to use this macro to be able to link to the library:

    #define PROCESSINGNDILIB_DEPRECATED

    Any ideas on what could be causing this issue?

    Cheers!

  2. #2
    Registered User roddyp's Avatar
    Join Date
    Sep 2017
    Location
    UK
    Posts
    54
    Possibly your compiler is packing the structure differently to the way the DLL expects it? The NDI_recv_create_V3_t is unusual in having a bool followed by a pointer, and different compilers can handle this differently.

    On your 32-bit system, what is sizeof(NDIlib_recv_create_v3_t)? I think it should be 24...

  3. #3
    LightWave Engineer Jarno's Avatar
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    618
    Another thing to look out for is that source_to_connect_to is an NDIlib_source_t, not a pointer to one. So setting it to nullptr may not be doing what you expect.

    ---JvdL---

  4. #4
    Registered User roddyp's Avatar
    Join Date
    Sep 2017
    Location
    UK
    Posts
    54
    Quote Originally Posted by Jarno View Post
    Another thing to look out for is that source_to_connect_to is an NDIlib_source_t, not a pointer to one. So setting it to nullptr may not be doing what you expect.
    That should be OK. It's one of the dustier corners of C++, but I think the assignment invokes the NDIlib_source_t constructor, with nullptr as the first parameter, and the second coming from the constructor's default (NULL).

    NDIlib_source_t(const char* p_ndi_name_ = NULL, const char* p_url_address_ = NULL);

  5. #5
    Registered User
    Join Date
    Nov 2019
    Location
    Canada
    Posts
    11
    Thanks for the reply guys. I tried passing an NDIlib_source_t this way:

    const NDIlib_source_t test;
    receiverSettings.source_to_connect_to = test/*nullptr*/;

    And got the same crash. The SDK document says you should be able to pass it nullptr initially. On my 64-bit machine I get these sizes for the two:

    GCC 7.3.0 (64 bit):
    sizeof(NDIlib_recv_create_t) -> 40
    sizeof(NDIlib_recv_create_v3_t) -> 48

    GCC 5.3.0 (32 bit):
    sizeof(NDIlib_recv_create_t) -> 32
    sizeof(NDIlib_recv_create_v3_t) -> 32

    I did some testing with NDIlib_recv_create_t & NDIlib_recv_create_v2() and it looks like its limited to 640 x 360 no matter what size of frame its passed.

    Cheers!

  6. #6
    LightWave Engineer Jarno's Avatar
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    618
    The 640 x 360 resolution would be the preview stream. You get that when the bandwidth field in NDIlib_recv_create_t is set to zero (NDIlib_recv_bandwidth_lowest). The default constructor should have set it to NDIlib_recv_bandwidth_highest though.

    So maybe the default constructors aren't being used. Or maybe there is some mixup between 32bit and 64bit.

    ---JvdL---

  7. #7
    Registered User roddyp's Avatar
    Join Date
    Sep 2017
    Location
    UK
    Posts
    54
    Quote Originally Posted by rtavakko View Post
    GCC 5.3.0 (32 bit):
    sizeof(NDIlib_recv_create_t) -> 32
    sizeof(NDIlib_recv_create_v3_t) -> 32
    That's almost certainly the problem. My x86 compiler reports the structure size as 24 bytes, with the p_ndi_recv_name pointer starting at byte 20.

    It should look like this:
    NDIlib_source_t (two pointers, so 8 bytes)
    NDIlib_recv_color_format_e (enum, 4 bytes)
    NDIlib_recv_bandwidth_e (enum, 4 bytes)
    boolean allow_video_fields (1 byte)
    ... three bytes of padding, so pointer is 32-bit aligned...
    p_ndi_recv_name (pointer, four bytes)

    If the structure layout in your code doesn't match what the DLL expects, you'll hit all kinds of problems (which might explain why your "recv_bandwidth" is always at preview resolution)

    I'm not a GCC expert, but take a look at GCC's structure packing and alignment pragmas. You should be able to find settings that work to mimic the standard Microsoft compiler behaviour.

    https://gcc.gnu.org/onlinedocs/gcc-4...g-Pragmas.html

  8. #8
    Registered User
    Join Date
    Nov 2019
    Location
    Canada
    Posts
    11
    Nice, thanks for the link, I'll go through it and come back with results. For now I'll just work around the receiver not having a name. I guess its not really that important anyway for a receiver as much as it would be for a sender.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •