Jump to content

alvise

Members
  • Posts

    209
  • Joined

  • Last visited

Posts posted by alvise

  1. 33 minutes ago, dadreamer said:

    That's how some guy did that in Delphi.

    function GetBMP(playHandle: Longint): TBitmap;
    var rbs: PDWORD;
         ps: PChar;
         i1,i: longint;
         bSize: DWORD;
         ms: TMemoryStream;
    begin
       try
         result := TBitmap.Create();
         if playHandle < 0 then exit;
         bSize := 3000000;
         ms := TMemoryStream.Create;
         new(ps);
         GetMem(ps,bSize);
         new(rbs);
         if PlayM4_GetBMP(playHandle,ps,bSize,rbs) then begin
           i1 := rbs^;
           if i1>100000 then begin
             ms.WriteBuffer(ps[0],i1);
             MS.Position:= 0;
             result.LoadFromStream(ms);
           end;
         end;
       finally
         FreeMemory(ps);
         FreeMemory(rbs);
         ms.Free;
         ps :=nil;
         rbs := nil;
         ms := nil;
       end;
    end;

    But that bSize := 3000000; looks not an elegant enough, so I'd suggest using PlayM4_GetPictureSize and calculating the final buffer size as

    sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + w * h * 4

    But you may test with that for now to make sure everything is working. Another option would be to use the DisplayCallback, that is set by PlayM4_SetDisplayCallBack. There the frames should already be decoded and in YV12 format, therefore you'd have to convert them to a standard RGBA or any other format of your liking.

    I don't understand Delphi very well.

    I've added the VI's I've been working on. There's really nothing I'm doing wrong, right?

    Quote

    sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + w * h * 4

    -Where did "BITMAPFILEHEADER" and "BITMAPINFOHEADER" come from here?

     

    It makes more sense to use "PlayM4 Set Display CallBack" but I guess that requires a new effort. Right?

     

  2.  

    1 hour ago, dadreamer said:

    image.png.73bf2d67fa56639e521e73e9ff263b11.png.5efd970aedb3fbfd3b5e722e4b57b05f.png

    BTW did you test this?

    I don't really understand what rolf is trying to tell here. Even though I've read it many times.But I created and tried it as in the photo below.

    image.png.b0e98cb6bc19154d5ad4a1974a6c8750.png

       image.png.fa353334342f3c7fe9014c2f73f1e29c.pngThis is how I get a response.

     

    To be frank, I tried to apply what I understood from what Rolf said in the picture below, I don't know if it's correct.

    image.png.36a05dee070c0ab2ad0e019618b35d1e.png

  3. 25 minutes ago, Rolf Kalbermatter said:

    That would work, but you also need to wire the nBufSize parameter. Can you guess with what value?

    This is how I wired dwBufSize->nBufSize.

    Ok, I edited it as follows.

    image.png.73bf2d67fa56639e521e73e9ff263b11.png

    Currently "pJpeg" returns a value that constantly changes.
    But I guess I need to convert this value to an array to return an image.But it returns exactly the same value as ''dwBufSize''.

  4. 1 hour ago, Rolf Kalbermatter said:

    You definitely will need the PlayM4_InputData(). Somehow you must provide the decoder with the continuous stream of data packages. Then it may or may not choke on the NULL HWND and it may or may not store the decoded data somewhere internal in the port and if it doesn't choke on the NULL HWND AND does store the decoded data somewhere in the port, you can call the PlayM4_GetJPEG() data. But of course you need to provide a large enough buffer to it, so MAYBE you can first call it with a NULL pJpeg and nBufSize = 0 and use the pJpegSize to call it again with a properly allocated buffer. Lots of may and may not and the only one who can find out about that is you!

    Firstly, I sent 0 value to ''pJPEG'' parameter of ''PlayM4_GetJPEG'' function and 0 value to ''nBufSize'' parameter. Everything worked. ''PlayM4_InputData'' returned 1 value. But ''PlayM4_GetJPEG'' function returned 0 value.

    1 hour ago, dadreamer said:

    Just allocate an U8 array of "w * h * 3/2" size and pass into the function. You should receive a JPEG memory stream in the pJpeg array, that could be translated into a common LV array later.

    I made some plugins like below, but I don't understand exactly what you want to say here.

    Since I cannot directly create a constant U8 array and write it to its zero index (for example: 640*480*3/2=460800), I need to convert this result to U8 array, right?

    image.png.fee278109102f8903ef9225a0ec1e5f8.png

  5. 7 minutes ago, dadreamer said:

    Well, it's a bit unclear whether you really need it. I found some conversations, where the guys were passing NULL as hWnd to it, when they didn't want it to paint. Logically it should start the buffer copying and decoding along with the rendering of the contents to some window. But maybe it just prepares its internal structures and the window as the next one is PlayM4_InputData, which actually grabs the buffer.

    -I haven't tried, but I guess so.


     

    image.png.46fe4934708389848435ed56e9c1d730.png

    Now I want to adapt it to ''PlayM4_InputData'' labVIEW, but your previous idea was to replace it with ''PlayM4_GetJPEG''. So I'm looking into this function, but there is ''pJpeg'' in the parameters as in the picture below, what values should be sent to it and I guess its output should be an array of images, right? But here only DWORD returns a number in its output.

    image.png.8451925490edff98edaee590e4ead989.png

    image.png.234da2fba0ed9d1c9beb71bb1990657c.png

     

  6. image.png.e64f5ec7a6b567705776bb74dfc6782c.png

    I understand better by applying C language. Actually, this is the first thing that came to my mind. But I contradicted myself because I don't have a good command of C language.But I really think about your suggestion. I have a lot of things to reconsider for better mastery of C language.

    -Yes, I know it's "array size". 

    I created it as I showed above, but the labview crashes.

    image.png.96bd60c84a55734b63f2e2c6f0946149.png

    image.png.edd6679ee39defee6ed7039db5a7791e.png
    - 1024*1024= ''1048576'' Do I need to send the result of the multiplication of two numbers directly?

  7. 9 hours ago, Rolf Kalbermatter said:

    I'm saying you send NOTHING there.  This is the definition of the user event datatype and what you "send" there into that cluster makes absolutely no difference. You could just as well leave the entire Bundle by Name away. What is important is the data type that the LVEventData element defines, nothing else. And this data type must at ALL times match the data type setup on the C side for the user event data structure or VERY BAD things will happen.

    Thanks for the reply. I changed it like this.

    image.png.4765e330a89592bd13d2d4701b5c57cc.png

    4 hours ago, dadreamer said:

    Use that HikVision example and Windows Player SDK Programmer Manual to implement the decoder calls.

    I created it as you suggested. But there are 2 things I can't understand.
    -For "BYTE *pBuffer", is it necessary to convert the "Handle" array to string and then convert it back to U32 number?
    - For ''if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024*1024))'', is it necessary to transmit the result of multiplying the number here with ''1024*1024''?

  8. 30 minutes ago, dadreamer said:

    It was obvious. Strange that we couldn't get to it so long. I think the easiest way would be to alter the callback condition like this.

    In this case the NET_DVR_SYSHEAD packet will be posted regardless of the state of cbState button. You should receive it right after starting the playback.

    You're talking about the time here, right?image.png.d9bf7655334681d1b31864d4c730aa73.png

    I changed it as you said. The feedback comes directly when I press the Start button and it can save the header file.

    image.png.37a27e56c9adcd3484d59ed0c29a4c99.png

    I guess there is no need to save ''NET_DVR_STREAMDATA''.

    NET_DVR_SYSHEAD1.txt

  9.  

    image.png.4e2843cd92ab6f47a83e80440bcdbdce.png

    I ran a test as you said and nothing is returned. 

    I think I found the cause of the problem. Setting the status "cbState" to true false with the stream button in the stream fram was causing problems.

    image.png.d1608c92f9eb238345ec0e98adae4093.png

    It's an interesting situation... If I press the '''STOP'' button directly without disabling the 'STREAM' button (receiving data), then when 'START' button is pressed again (beacuse I set  "cbState" the constant True  function of the ''STREAM'' ), the data is directly initialized to NET_DVR_SYSHEAD However, if I send true-false to the "cbState" function in the "Stream" frame with the button, the "NET_DVR_SYSHEAD" value will not be read, but the stream can be stopping and restarting.

  10. 1-) 

    By the way, ''dwDataType'' only returned 1 once, otherwise it always returned 2.

    I am getting output as below. But still value 1 is not returned and therefore I could not create NET_DVR_SYSHEAD packet save.

    image.png.8a2a78514948bec795bd06160615e0f0.png

    image.png.074e584d91c41707282846d6af101f45.png

     

    2-)

    While trying to understand (which I still don't understand) how to modify the C++ code, one more thing caught my attention.
    There is a dll file like below, isn't there a shorter way to get video stream information using it?
    The function names in this dll file match the function names shown in the sample code here, and there is also a user guide of this dll file as below.
    Of course, a callback is required under all circumstances.

     

    PlayCtrl.dll Windows Player SDK Programmer Manual (Version 6.2.XX).pdf

  11. 10 minutes ago, dadreamer said:

    - The "1" case is for NET_DVR_SYSHEAD capture, but you assign NET_DVR_STREAMDATA name inside it; the "2" case is for NET_DVR_STREAMDATA capture.

    - You have unwired tunnel for blue wire in some frames of the Event Structure. Don't you see that small rect is not painted completely?..

    It's senseless! You can input any values in that cluster constant and this changes literally nothing. This constant is only to define the User Event data type and that's all.

    -I set it that way because ''dwDataType'' never returns a value of 1.

    image.png.ba5e864db89cff2518ae927faa46c867.png-After the explanations above, I stopped assigning a value to the cluster elements. I fixed it.

    15 minutes ago, dadreamer said:

     

    So can you call the functions from the PlayM4 SDK now? You need to find a suitable function to decode the stream and receive a ready-to-use bitmap or pixels array. I don't know exactly which one is okay as I can't find the documentation (but I barely searched, to be honest, because was busy today).

    Ok, I found these:

    //get bmp or jpeg
    PLAYM4_API BOOL __stdcall PlayM4_GetBMP(LONG nPort,PBYTE pBitmap,DWORD nBufSize,DWORD* pBmpSize);
    PLAYM4_API BOOL __stdcall PlayM4_GetJPEG(LONG nPort,PBYTE pJpeg,DWORD nBufSize,DWORD* pJpegSize);

    Do you have them in your headers?

    Yes the header file contains these calls but I don't know how to use them in C++ code. I will try to do that.

  12. 22 minutes ago, Rolf Kalbermatter said:

    Second,which dwDataType are you talking about? The dwDataType in the callback routine is not something you should change at all. It is what the SDK driver returns to you and that's it. That is the definition of a callback, it is called by the other software component with values that you should use, not manipulate unless the callback function documentation states explicitly that you are expected to return some data in one or more of the passed in buffers.

    image.png.9204883e29e0c05121d6f2a18b983149.png Are you saying it's unnecessary to send any value to "dwDataType" like in the photo?

     

    23 minutes ago, Rolf Kalbermatter said:

    Of course, and where did you get that header from?

    This header is available in the provided SDK files.

    33 minutes ago, Rolf Kalbermatter said:

    It can never compile in any C compiler that I know of. But it would help if you use generally accepted terms in your communication. A CRASH is something that occurs AFTER you have COMPILED and LINKED your application and start it. I usually means that your process dies with or without an according error message. What you encountered was a COMPILE ERROR since the compiler could not understand the code statement.

    .After importing the ''play mpeg 4.h'' header in the C++ code, an error occurred, I wanted to say that this compilation error has disappeared.

    Yes it was a compilation error.Sorry,I have problems with some terms :)

    I'm looking at this sample code as I don't have a solution at the moment. How can we use this sample code to achieve the desired result?

  13.  

    When I make a change like below, it only saves one file, shouldn't it save a new file for each event iteration? Why does it only save one file? Is the method I'm using correct?

    image.png.aa985b14488907a7631b43f49e05bf2f.png

    1 hour ago, dadreamer said:

    It's difficult for me to find the errors source from your screenshot.

    These errors appear in the "plaympeg 4.h" file.

    Quote

    PLAYM4_API DWORD __stdcall PlayM4_GetSourceBufferRemain(LONG nPort);

    Error    C4430    missing type specifier - int assumed. Note: C++ does not support default-int    hikLabview-0.0.01 

    Quote

    PLAYM4_API BOOL __stdcall PlayM4_Stop(LONG nPort);

    Severity    Code    Description    Project    File    Line    Suppression State
    Error    C2146    syntax error: missing ';' before identifier 'BOOL'    hikLabview-0.0.01      line 299    

    -I think here is the reason for the error;
    Because "BOOL" is written in capitals, if I write it small, the problem disappears, but I don't know if it creates a different problem.

  14.  

    12 minutes ago, dadreamer said:

    Maybe. I've been browsing their samples too. Looks like they use a custom MPEG-4 decoder. In NET_DVR_SYSHEAD case they just initialize the decoder as this is the very first frame. But seems that the actual pBuffer contents of the system header aren't used in any way. Or I'm wrong? Later in NET_DVR_STREAMDATA case they obtain the packets and render them into a separate window using that MP4 decoder. Maybe it would be easier to use it instead of reinventing not only a wheel, but an entire car. Could you try to #include "plaympeg4.h" header to your code and recompile? Do you receive any errors?

    Yes, I'm getting errors like the following. I'm looking at all the examples, similar examples have been created.

    image.png.01174d35a8c1fe65a7267827f52d5755.png

    plaympeg4.h

     

    17 minutes ago, dadreamer said:

    Normal button is not suitable here due to the reasons I explained earlier. You could try to generate a random file name on each packet arrival (say, packet number or current date + time or something else), so the data gets recorded into a new file instead of being written to the same file.

    With the method you suggested, it is necessary to stop and restart the VI for each new package. It should be like this, right?

     

    NET_DVR_STREAMDATA NEW.rar

  15.  

    -I'm reviewing the example here. I guess the 'NET_DVR_SYSHEAD' package is required.

    Quote

    11 hours ago dadreamer said:
    Maybe you can collect and upload a few different (or more) files?


    -I couldn't quite understand what you said here, do you want me to record in my record before?

    I took a few records as below and created a record with the normal button.

     

     

    NET_DVR_STREAMDATA.rar

×
×
  • Create New...

Important Information

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