Jump to content

alvise

Members
  • Posts

    209
  • Joined

  • Last visited

Posts posted by alvise

  1. Something caught my attention here.

    -If I set 'dwDatatype' to 1 it returns output like this.image.png.d89aa95cb65fe8a69746684395f5d2d7.png

    -If I set 'dwDatatype' to 2 it returns output like this.image.png.2b4db90ce6535247cb79ca54399d8f07.png

    As you change the 'dwDataType' from 1 to 2 and run it again, the 'SetCbState return' number value increases. But if I run it again without changing the 'dwDataType', the value of ''SetCbState return'' remains constant. Is there any relation between the number returned by ''SetCbState'' and ''DwDataType''? Why does it have such an effect?

  2. 6 hours ago, dadreamer said:

    In some of your previous tests you showed that NET_DVR_SYSHEAD arrives first and is followed by a sequence of NET_DVR_STREAM_DATA packets. I can't say now, whether we really need NET_DVR_SYSHEAD to analyse NET_DVR_STREAM_DATA, but it would be useful to have both of them.

     

    I thought NET_DVR_SYSHEAD was saved, but "dwDataType" always returns 2.- I have no idea why ''dwdataType'' is not returning 1. What could be the problem here?


    -I try as follows, but the size of the array does not remain constant, it constantly changes between 0 and 4350

     

    image.png.045c443ea9a5d02059d131033dd519ba.png

  3. 58 minutes ago, dadreamer said:

    You mean using NET_DVR_SetRealDataCallBack instead of NET_DVR_SetStandardDataCallBack?

    So could you do this then? We can't go on without looking at the data as nobody except you has that hardware here. Of course, you may figure out the format of the data on your own, if you wish.

    -yes because ''NET_DVR_Set Standard Data CallBack'' causes problems.

    -I changed the datatype(dwDataType) to 2.

    -Is it necessary to capture the NET_DVR_SYSHEAD (1) packet?

    -How do I catch a packet that I don't understand at the moment :)

  4. I still think there is a possibility that the "session" value here is causing a problem.
    I believe the number here should not change. In order for this number to be a fixed number, I made some changes as follows. But the number is still changing. Don't you think this will cause a problem?

    Preview CAM-9.vi

    image.png.c540e6ec7222f1bd96737f4b58a7b385.png

    image.png.1e79d293515b5c86d93f7294d3bd638a.png

     

    7 minutes ago, Rolf Kalbermatter said:

    Did you change the function to actually return a value? In the last code you posted the SetCbState() function returns void. That means you can configure the Call Library Node to return an integer value,

    I tried and tested a change as you said in the attached VI.

    Based on the code you shared, I will make changes to the dll code and compile and test it again.

     

  5. 3 hours ago, dadreamer said:

    Press 'Start" -> press "Stream" -> the data is being read -> un-press "Stream" -> press "Stop" -> again press "Start" -> again press "Stream" -> the data is being NOT read... Is that your order of actions?

    Yes, this is it. Sometimes there is data, sometimes not.

    3 hours ago, dadreamer said:

    By the way, do you know that InstallStandardCallback has return value?

    2022-06-03_10-00-39.jpg.008c692b25eb7c547c08ff679be7cb45.jpg

    You have set it to void in the CLFN settings, but it should be Numeric -> Signed 32-bit Integer. So let's check that value. Put two indicators on your FP from both InstallStandardCallback calls and watch which values they obtain in "good" and in "bad" case. According to the documentation for NET_DVR_SetStandardDataCallBack TRUE (1) means success, FALSE (0) means failure and NET_DVR_GetLastError should be called to find out the reason behind the error.

    When I test with the above order. The results are as follows.

    By the way, I set the returns as 32 bit signed integer.

    image.png.2e58b75b6c8afbc0d4fad37b93c73ae6.png- ''Callback start return '' If it takes the value '1'. Data can be read. If it takes the value '0', the data cannot be read.

    -The "SetCbState" value gets a new random value when the VI is completely shut down and restarted. For example, if VI is opened, the values will show as ''0'' and when run it will return ''324433408''.
    If the VI is completely closed and reopened, it gets the value "418927872". However, in the numbers I gave above, the last value is one up and one down (418927871-418927872) in sync with the "Stream" button.

     

    -"stop callback" changes from 1 to 0 each time it is turned on and off. In other words, there is no connection with whether there is data according to the value of 0 or 1. Sometimes data is read even if a value of 1 is returned, sometimes data is read even if a value of 0 is returned. Sometimes the opposite happens and the value is not read.

  6. OK. In order not to take too long, I did some tests myself here. Let me explain the test and the result first.
    Note: I did this test with the VI that I shared last and that you said looks good.

    - After pressing the "Run" button, I press the "Stream" button, the data can be read, then I press the "Stop" button and the data flow is stopped. If I press the "Start" button again without pressing the "Exit" button, the data will not be read. I press the stop button again.
    When I test it by following a sequence. Mostly data is read once and not read once.
    Actually, there is one more thing I suspect now.
    -Why does the Session number here change between 0 and 1 every time I run and close the VI.
    If I run VI, "Session" will get 1, and if I turn it off and on again, it will get 0. This is in a loop, the value of the session is changing every time I run it. It sounds like this might be causing a problem. Shouldn't this number stay the same all the time?

    image.png.b0603b129135375c579892e78f25f647.png

    image.png.657f262a12bebbcb56ddff5706cfe742.png

     

  7. Neil and Rolf Thanks for the explanation. 

    I have noticed before that it is difficult to write some programs in Labview. I have been working with LabVIEW for a long time because Labview is a language with some advantages. My command of other languages was not that good and was forgotten.

    By the way, I'm not doing this to get a payment. I'm just doing it to help someone. When I started to create this Application, I honestly did not anticipate that it would be such a deep job. Therefore, I never anticipated the time it would take.

  8. 48 minutes ago, dadreamer said:

    Seems more or less ok. But better to place UninstallCallback CLFN in the "stop" frame as you install the callback in the "start" frame. I also assume you're passing NotARefnum as Adapt to Type -> Handles by Values with cdecl convention.

    Wait, I've just thought it would be good to have an organized dataflow in both "start" and "stop" frames. In "start" first do the event handling (registration etc.), then call Start.vi, then install the callback. In "stop" do in the opposite order. You may easily set the dataflow order with two ways: either with brown error wire or with Sequence Structure. There's a State Machine pattern as well, but I feel you're not ready to remake all the program right now.

    I created something like below, but I followed exactly what you said, maybe there are faulty points.
    If ok, I will proceed accordingly.

    Preview CAM-7.vi

  9.  

     

    24 minutes ago, ShaunR said:

    Nope. The main problem is you are "learning" by doing something that 98% of the LabVIEW community couldn't do. I'm nowhere near as capable as Rolf or dadreamer on this stuff and if a client had asked me to do it I would have "declined to quote".

    Yes, I know it's something not everyone can do, but there is no alternative. By the way, I don't understand what you mean by "declined to quote" :)

  10. Neil Pate

    You are right But the problem is that simple piece of code may not be the problem. The problem arises when the code starts to get complicated. My main problem is concepts and topics that I am unfamiliar with, so I'm starting from the basics again.

     

    dadreamer 

    The question is, what code do I need to compile as Rolfk suggested?
    Ok, I will go step by step.
    Step 1: Finally, I changed it as follows and compiled it again. and I used this in Preview CAM.vi. But still the problem persists.

    If that's true, let's discuss its use in LabVIEW, if not, I'll try to get the C code working first.
    - To begin with, is the following code correct?

     

    #include "extcode.h"
    #include "hosttype.h"
    #include "HCNetSDK.h"
    
    #define LibAPI(retval)       __declspec(dllexport) EXTERNC retval __cdecl
    #define Callback(retval)     __declspec(dllexport) EXTERNC retval __stdcall
    
    // Define LabVIEW specific datatypes to pass data as event
    // This assumes that the LabVIEW event datatype is a cluster containing following elements in exactly that order!!!
    // cluster
    //   int32       contains the current live view handle 
    //   uInt32      contains the dwDataType (NET_DVR_SYSHEAD, NET_DVR_STD_VIDEODATA, NET_DVR_STD_AUDIODATA, NET_DVR_PRIVATE_DATA,
    //                                        or others as documented in the NET_DVR_SetStandardDataCallBack() function
    //   array of uInt8     contains the actual byte stream data
    #include "lv_prolog.h"
    typedef struct
    {
    	int32_t size;
    	uint8_t elm[1];
    } 
    LVByteArrayRec, * LVByteArrayPtr, ** LVByteArrayHdl;// ** LVByteArrayHdl;pointer to a pointer
    
    typedef struct
    {
    	LONG realHandle;
    	DWORD dataType;
    	LVByteArrayHdl handle;
    } LVEventData;
    #include "lv_epilog.h"
    extern "C" __declspec(dllexport) void __cdecl SetCbState(LVBoolean * state);
    // where Standard Boolean type case is set: typedef uInt8 LVBoolean
    LVBoolean cbState = LVBooleanFalse;
    // always set to false on startup
    extern "C" __declspec(dllexport) void __cdecl SetCbState(LVBoolean * state)
    {
    	cbState = *state;
    }
    extern "C" __declspec(dllexport) void __stdcall DataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE * pBuffer, DWORD dwBufSize, DWORD dwUser)
    {
        if (cbState == LVBooleanTrue)
        {
            LVEventData eventData = { 0 };
            MgErr err = NumericArrayResize(uB, 1, (UHandle*)&(eventData.handle), dwBufSize);
            if (!err)// send callback data if there is no error and the cbstatus is true.
            {
                LVEventData eventData = { 0 };
                MgErr err = NumericArrayResize(uB, 1, (UHandle*)&(eventData.handle), dwBufSize);
                LVUserEventRef userEvent = (LVUserEventRef)dwUser;
                MoveBlock(pBuffer, (*(eventData.handle))->elm, dwBufSize);
                (*(eventData.handle))->size = (int32_t)dwBufSize;
                eventData.realHandle = lRealHandle;
                eventData.dataType = dwDataType;
                PostLVUserEvent(userEvent, &eventData);
                DSDisposeHandle(eventData.handle);
            }
        }
    }
    
    //If the above if condition does not occur, the LVUserEventRef here does not take a value.
    typedef BOOL(__stdcall* Type_SetStandardDataCallBack)(LONG lRealHandle, void(CALLBACK* fStdDataCallBack) (LONG lRealHandle, DWORD dwDataType, BYTE* pBuffer, DWORD dwBufSize, DWORD dwUser), DWORD dwUser);
    extern "C" __declspec(dllexport) BOOL __cdecl InstallStandardCallback(LONG lRealHandle, LVUserEventRef * refnum)
    {
        HMODULE hDLL = LoadLibraryW(L"HCNetSDK.dll");
        if (hDLL)
        {
            Type_SetStandardDataCallBack installFunc = (Type_SetStandardDataCallBack)GetProcAddress(hDLL, "NET_DVR_SetStandardDataCallBack");
            if (installFunc)
            {
                if (refnum && *refnum)
                    return installFunc(lRealHandle, DataCallBack, (DWORD)(*refnum));
    
            }
            FreeLibrary(hDLL);
        }
        return FALSE;
    }

     

     

     

  11. Sometimes there are situations where I am torn between doing it right or not.
    For example:
    At first I thought the uninstallcalback had to be created in labview because I read a post of yours that talked about creating "uninstallcalback.vi".
    Then I realized after reading a post you wrote that it is not possible to create it only in labview. Because you said I should use ''not A Refnum''. I interpreted this as ''not A refnum'' should have an equivalent in C++ code. I struggled to create and export a function called unInstallStandardCallback. but I was torn between whether I was doing it exactly right or not.

    Then I deduced that in order to use ''not A refnum'', a ''Not A refnum'' should be sent to the parameters of the InstallStandardCallback function created without making any changes in the c++ code. Because if no reference is sent, ''return installFunc(lRealHandle, NULL, 0); I interpreted the '' will work and set the values to zero and that way the callback will be removed.
    I tend to be wrong in this inference, although it is still unclear.
    -It's a bit difficult for me to create this Example, but I have to do it because I have no other alternative.
    So I need to do some good research and testing to better understand the situation. After reading what you wrote, I guess it won't be easy to create a VI to parse MPEG4 or H.264 data.

    I can't insist that anyone help with this. I have no right to waste anyone's time because there are so many situations that I don't understand that I'm between 2 programming languages and there are some problems in both languages that I don't understand. An extra broad topic, callbacks and tokens, I'm sure is no ordinary university issue.I'm not a university student either.I'm a casual person struggling to create a sample application that can only use labview.I am not really a Developer, just eager to learn programming.

     

    Thank you everyone for your help.

  12. actually it has a very simple answer. I don't know exactly how to do it.

    I guess sometimes "NET_DVR_SetStandarData CallBack" causes unreadable data.

    #include "extcode.h"
    #include "hosttype.h"
    #include "HCNetSDK.h"
    
    #define LibAPI(retval)       __declspec(dllexport) EXTERNC retval __cdecl
    #define Callback(retval)     __declspec(dllexport) EXTERNC retval __stdcall
    
    // Define LabVIEW specific datatypes to pass data as event
    // This assumes that the LabVIEW event datatype is a cluster containing following elements in exactly that order!!!
    // cluster
    //   int32       contains the current live view handle 
    //   uInt32      contains the dwDataType (NET_DVR_SYSHEAD, NET_DVR_STD_VIDEODATA, NET_DVR_STD_AUDIODATA, NET_DVR_PRIVATE_DATA,
    //                                        or others as documented in the NET_DVR_SetStandardDataCallBack() function
    //   array of uInt8     contains the actual byte stream data
    #include "lv_prolog.h"
    typedef struct
    {
    	int32_t size;
    	uint8_t elm[1];
    } 
    LVByteArrayRec, * LVByteArrayPtr, ** LVByteArrayHdl;// ** LVByteArrayHdl;pointer to a pointer
    
    typedef struct
    {
    	LONG realHandle;
    	DWORD dataType;
    	LVByteArrayHdl handle;
    } LVEventData;
    #include "lv_epilog.h"
    extern "C" __declspec(dllexport) void __cdecl SetCbState(LVBoolean * state);
    // where Standard Boolean type case is set: typedef uInt8 LVBoolean
    LVBoolean cbState = LVBooleanFalse;
    // always set to false on startup
    extern "C" __declspec(dllexport) void __cdecl SetCbState(LVBoolean * state)
    {
    	cbState = *state;
    }
    // cbstate does a state reassessment.True or False
    // cbstate does a state reassessment.True or False
    extern "C" __declspec(dllexport) void __stdcall DataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE * pBuffer, DWORD dwBufSize, DWORD dwUser)
    {
        if (cbState == LVBooleanTrue)
        {
            LVEventData eventData = { 0 };
            MgErr err = NumericArrayResize(uB, 1, (UHandle*)&(eventData.handle), dwBufSize);
            if (!err)// send callback data if there is no error and the cbstatus is true.
            {
                LVEventData eventData = { 0 };
                MgErr err = NumericArrayResize(uB, 1, (UHandle*)&(eventData.handle), dwBufSize);
                LVUserEventRef userEvent = (LVUserEventRef)dwUser;
                MoveBlock(pBuffer, (*(eventData.handle))->elm, dwBufSize);
                (*(eventData.handle))->size = (int32_t)dwBufSize;
                eventData.realHandle = lRealHandle;
                eventData.dataType = dwDataType;
                PostLVUserEvent(userEvent, &eventData);
                DSDisposeHandle(eventData.handle);
            }
        }
    }
    
    //If the above if condition does not occur, the LVUserEventRef here does not take a value.
    typedef BOOL(__stdcall* Type_SetStandardDataCallBack)(LONG lRealHandle, void(CALLBACK* fStdDataCallBack) (LONG lRealHandle, DWORD dwDataType, BYTE* pBuffer, DWORD dwBufSize, DWORD dwUser), DWORD dwUser);
    extern "C" __declspec(dllexport) BOOL __cdecl InstallStandardCallback(LONG lRealHandle, LVUserEventRef * refnum)
    {
        HMODULE hDLL = LoadLibraryW(L"HCNetSDK.dll");
        if (hDLL)
        {
            Type_SetStandardDataCallBack installFunc = (Type_SetStandardDataCallBack)GetProcAddress(hDLL, "NET_DVR_SetStandardDataCallBack");
            if (installFunc)
            {
                if (refnum && *refnum)
                    return installFunc(lRealHandle, DataCallBack, (DWORD)(*refnum));
                else
                    return installFunc(lRealHandle, NULL, 0);
            }
            FreeLibrary(hDLL);
        }
        return FALSE;
    }

     

    This is how it looked when you first posted the code (referring to the code dadreamer shared).

    typedef BOOL(__stdcall *Type_SetStandardDataCallBack)(LONG lRealHandle, fStdDataCallBack cbStdDataCallBack, DWORD dwUser);
    
    LibAPI(BOOL) InstallStandardCallback(LONG lRealHandle, LVUserEventRef *refnum)
    {
    	HANDLE hDLL = LoadLibraryW(L"HCNetSDK.dll");
    	if (hDLL)
    	{
    		Type_SetStandardDataCallBack installFunc = (Type_SetStandardDataCallBack)GetProcAddress(hDLL, "NET_DVR_SetStandardDataCallBack");
    		if (installFunc)
    		{
    			return installFunc(lRealHandle, DataCallBack, (DWORD)(*refnum));
    		}
    		FreeLibrary(hDLL);
    	}
    	return FALSE;
    }

     

  13. No, no changes have been made here.

    extern "C" __declspec(dllexport) BOOL __cdecl InstallStandardCallback(LONG lRealHandle, LVUserEventRef * refnum)
    {
        HMODULE hDLL = LoadLibraryW(L"HCNetSDK.dll");
        if (hDLL)
        {
            Type_SetStandardDataCallBack installFunc = (Type_SetStandardDataCallBack)GetProcAddress(hDLL, "NET_DVR_SetStandardDataCallBack");
            if (installFunc)
            {
                if (refnum && *refnum) 
                    return installFunc(lRealHandle, DataCallBack, (DWORD)(*refnum));
                else
                    return installFunc(lRealHandle, NULL, 0));
            }
            FreeLibrary(hDLL);
        }
        return FALSE;
    }

     

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.