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
    9

    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
    610
    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
    9
    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
    610
    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
    9
    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
  •