LCF-AT Posted June 27, 2016 Posted June 27, 2016 Hi guys, so I got following problem.So you know the VLC player which you can also use to enter direct URL addresses of video files to play them.If I use this function then all is working well and the video will played normaly and liquid as it should.Now I wrote a WinSock code to download the bytes and write them into a name pipe handle created for VLC process and started the player via ShellExecuteEx.The VLC player starts and does play the video reading the bytes from pipe.All is working fine so far but the video dosent play liquid and it lags / jerky etc so its not good and also not playing same if I enter the URL in VLC.So I dont find the problem reason in this case.In short my way looks so.. socket connect send VLC_PIPE ; create pipe & start VLC via ShellExecuteEx //////////////////////// LOOP: recv WriteFile ; datas to pipe handle FlushFileBuffers ...as I said all is working except the problem that the video playing lags etc.The buffer for recv API is also large enough (1024*1024*10) I created with HeapAlloc API.Has anyone a idea what the problem could be?Maybe I need to use another WinSock APIs etc?Also if I pause the video for some seconds and let play it again then it still lags and many frames get lost.I also tried to use some commandline paramters for VLC in the SHELLEXECUTEINFO struct like --file-caching xy which also get set but it has no effect.Maybe you know whats going on and how to fix that problem. Thanks
atom0s Posted June 27, 2016 Posted June 27, 2016 Personally, I have always had bad experiences with named pipes with lag as well as random crashing after the pipe just dies for no reason. I would recommend trying to implement your own pipe/protocol using memory mapped files instead. They are a lot more stable and much faster than named pipes in my testing in the past. 2
LCF-AT Posted June 28, 2016 Author Posted June 28, 2016 Thanks for your answer so far but normaly I always use named pipes also with librtmp and never got any problems so far.So somehow it should work but how is the question. Do you have any example or description how to do it with your method? greetz
atom0s Posted June 28, 2016 Posted June 28, 2016 When I was developing some packet bots for MMORPGs I started testing with named pipes and in high-flow traffic named pipes always broke and gave me problems. They were extremely slow as well and were not suitable for ensuring the traffic was handled immediately / when it came in etc. I switched to memory mapped files to get what I needed working in a much better manner stress testing with 10,000 test packets of data in milliseconds. I don't have an example I can share, the source code for that stuff is copywritten and commercial, but I can help you create something similar. In terms of the API needed, you will need: CreateFileMapping MapViewOfFile UnmapViewOfFile CloseHandle With CreateFileMapping you will create a mapping with a total buffer size of what you want to allow to be placed into the buffer. Also with that, add some space at the start of the buffer for some custom data to handle when the buffer is clean/ready for more data. So for example, you could have something like: #define MMF_MAX_BUFFER_SIZE 0xA00004 The starting part of the buffer can hold something like: struct Buffer { unsigned int Timestamp; unsigned char Buffer[0xA00000]; }; The timestamp here could be used to hold when your buffer was last written to, useful to ensure that data is not being overwritten and is being handled by your app immediately. That said, you should send the data to VLC in whatever manner you are using, and clear the buffer to ready it for the next write immediately. You want to be sure that the MMF is always free and clear to keep accepting data. Another method you can do to ensure that is having a thread reading the MMF constantly for new data to be written (monitoring the Timestamp for a new value that is not 0 and does not match the previous timestamp it read) then copying the Buffer out into a local storage buffer to be handled within VLC etc. 1
LCF-AT Posted June 28, 2016 Author Posted June 28, 2016 Hi again, hhmm.So I tried already to copy all received bytes from revc to my own buffer location which has a size of 200000h bytes.Now I wait so long till my buffer has filled +100000h bytes and then I create the pipe and write the 100000h bytes to pipe handle and right after this I use the old buffer location again which gets filled / wriiten / erased etc.Problem now is that the video dosent play anymore.Just see the first few frames of the video then no more frames are comming but the time of VLC video is running forward normaly!?That really sucks.I also asked kao about that problem and kao said to use MSG_WAITALL flag for recv API and its working for kao but in my case I can't use this flag so it seems not to work on XP 32bit and just get WSAEOPNOTSUPP error on recv API.Uhmmm!Such a BS! greetz
LCF-AT Posted July 30, 2016 Author Posted July 30, 2016 Hi guys, today I have a new question about pipes and set the question into this topic to prevent another topic.So its a tiny question and need some help so I dont get alone again. Question: How to build unnamed / anonymous pipes instead named pipes?Following problem.I would like to execute a extern player app like VLC or MPC-HC but this time only with not named pipes.VLC player does support named pipes I can also use but MPC-HC dosent support named pipes only stdin pipe and here I have to use a other way I dont get it work.Below a short example for named pipe. CreateNamedPipe = PIPEHANDLE ShellExecuteEx SHELL.cbSize, sizeof SHELLEXECUTEINFO SHELL.fMask, SEE_MASK_NOCLOSEPROCESS SHELL.lpFile, offset VLC_PLAYPATH (c:\vlc.exe) SHELL.lpParameters, offset PPARAM (stream://\\\.\pipe\streamer) SHELL.nShow, SW_SHOW ConnectNamedPipe (PIPEHANDLE) WriteFile (PIPEHANDLE) (writes bytes from my buffer into pipe) FlushFileBuffers (PIPEHANDLE) CloseHandle (PIPEHANDLE) TerminateProcess (SHELL.hProcess) Now I need almost same just for unnamed pipe to get it also working with players like MPC-HC who dont support named pipes but here I do stuck and dont get it work.So maybe anyone of you does know it how the code has to look (API way) for unnamed pipe.If I see it right then I cant also use ShellExecuteEx API and need to use CreateProcess etc.Also tried this anyhow but dont get it work so I still do something wrong. Thank you
fearless Posted March 26, 2017 Posted March 26, 2017 (edited) -deleted- Edited March 26, 2017 by fearless wrong window replied to - oops
LCF-AT Posted April 7, 2017 Author Posted April 7, 2017 (edited) Hi again, so after a lot of testing I see that this pipe method using named pipe (as I did post above) dosent work good and seems to be a bad idea using it with video streams (lags / hangs / jumps etc).Now I switched back using anonymous pipe method which works a lot better. But now I have a other little problem with that and wanna find a solution.So before I used NamePipe and started VLC player (see above) and if I did press the stop button in VLC player then it also did close the player.So this was the advantage of Name pipe method.Now if I use anonymous pipe method it keeps connected if I press stop button in VLC player and I need to exit the player manually.My question is whether there is also a way to check if the pipe is still active in VLC etc? greetz EDIT: So the problem is also if I press stop in VLC or exit VLC that I will not come back from write API.Its hangs inside.So how can I check this pipe before writing bytes to prevent a no return from write API? Edited April 8, 2017 by LCF-AT Just edit...
ragdog Posted April 8, 2017 Posted April 8, 2017 (edited) Hello I´m not experience about Name pipe but if i use google tell me you can check it with ReadFile. while True: ret_code = ReadFile() if ret_code == 0 and GetLastError() == ERROR_BROKEN_PIPE: # client disconnected Check it out and post a solution. But i think you ask on a wrong Board on a programming Board (Cpp/Masm32) have you faster a solution. Regards, Edited April 8, 2017 by ragdog
LCF-AT Posted April 8, 2017 Author Posted April 8, 2017 Hi raggy, so the named pipe does work without to check the read pipe handle but disadvantage is that I get this playing lag / fame dropping issues = sucks.If I use anonymous pipe then I dont get any lag playing issues anymore = good but I cant check whether the pipe is still active in the player anyhow.Only thing what I can do is to close the read pipe handle after creating the pipe and if I exit VLC manually then it will also come back from write API where I then can clean the rest etc. So the problem is to find out whats the right and best method. NamedPipe: +Dosent hang in write API (Has overlapped feature) // - Playing lags AnonymousPipe: -Does hang in write API till I exit VLC player (need to close read pipe handle before) // + Playing fine // - Cant read the readpipe handle Normaly I would still NamedPipe if it would not lag.The question is why it does lag.Maybe it has something to do that I use for NamedPipe ShellExecuteEx and or AnonPipe CreateProcess API.Also found any info on internet not to use NamedPipe for Client and should use CreateFile / read / write API. AnonymousPipe ------------------------ invoke CreatePipe,addr HREAD,addr HWRITE,addr SECURITY,0 invoke SetHandleInformation,HWRITE,HANDLE_FLAG_INHERIT,0 mov eax, HREAD mov startupinfo1.hStdInput,eax mov eax,HWRITE mov startupinfo1.hStdOutput,eax invoke CreateProcess,NULL,addr VLC_PLAYPATHBUFFER ,NULL,NULL,TRUE,NULL,NULL,NULL,addr startupinfo1,addr pinfo invoke CloseHandle,HREAD Here I read bytes from internet constantly = InternetBytes / InternetSize The bytes I do send to WriteFile API into HWRITE handle invoke WriteFile,HWRITE,InternetBytes,InternetSize,addr numberBytesWrittennew,offset overlapped --------------------------------------------------------------- Now if I press Stop button in VLC then it does hang in WriteFile API so long till I close VLC player and then it comes back.Thats the problem here. NAMEDPIPE ------------------------- invoke CreateNamedPipe,offset PNAME,PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE or PIPE_READMODE_BYTE or PIPE_WAIT,1,1024*64,1024*64,NMPWAIT_USE_DEFAULT_WAIT,0 mov esi, eax invoke ShellExecuteEx,addr SHELL // VLC invoke ConnectNamedPipe,esi,0 Here I read bytes from internet constantly = InternetBytes / InternetSize invoke WriteFile,esi, InternetBytes,InternetSize,addr numberBytesWrittennew,offset overlapped ----------------------------------------------------------------- Here its working and it does not hang in WriteFile API if I press Stop button in VLC and it comes back with eax 0 and I can terminate VLC and cleanup the rest.Only problem for this method is the lag / frame dropping issues. Maybe you or anyone else has some another ideas. greetz
ragdog Posted April 8, 2017 Posted April 8, 2017 (edited) Hello I think it works a named pipe is similar to get the pipe from console output from created process. mov SA.nLength, sizeof SECURITY_ATTRIBUTES mov SA.lpSecurityDescriptor, NULL mov SA.bInheritHandle, TRUE invoke CreatePipe, addr hRead, addr hWrite, addr SA, NULL invoke RtlZeroMemory, addr StIn, sizeof STARTUPINFO mov StIn.cb, sizeof STARTUPINFO invoke GetStartupInfo, addr StIn mov eax, hWrite mov StIn.hStdOutput, eax mov StIn.hStdError, eax mov StIn.dwFlags, STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES mov StIn.wShowWindow, SW_HIDE invoke RtlZeroMemory, addr PI, sizeof PROCESS_INFORMATION invoke CreateProcess, NULL, addr Buffer, NULL, NULL, TRUE, NULL, NULL, NULL, addr StIn, addr PI .if (eax) invoke CloseHandle, hWrite .while TRUE invoke RtlZeroMemory, addr Buffer, sizeof Buffer invoke ReadFile, hRead, addr Buffer,sizeof Buffer, addr nOfBytes, NULL .if (eax) .if nOfBytes != 0;Error = bytes read. It read from Created pipe from hRead. You can correct me if i wrong but i think is similar. Cherrs, Edited April 8, 2017 by ragdog 1
LCF-AT Posted April 8, 2017 Author Posted April 8, 2017 Hi raggy, no it dosent work.VLC player send error messages if it starts.Also I need to use SetHandleInformation too without it dosent work.Anyway if I keep read & pipe handles then it will also hang inside and dosent come back in readfile API for read pipe handle from the beginning.Just if I close the read pipe hanlde then writefile API will come back but just if I exit VLC player. So I only have the write pipe handle where I can send my bytes into but I need to find any check method before writefile API but how. I just can exit VLC manually but this I dont prefer and want it auto closed if the video stream isnt active anymore.As I said,with NamedPipe method it does work as I want but this has the stupid lag problem. Here I found some new infos.... http://stackoverflow.com/questions/60645/overlapped-i-o-on-anonymous-pipe ....not sure whether this could work or not. greetz
LCF-AT Posted April 11, 2017 Author Posted April 11, 2017 Hi again, so I still try to find a way how to catch the info if when I do press STOP button in VLC player (if I use anonymous pipe).So as I told above if I press stop then it hangs in writefile API till I exit VLC and then it comes back. My question now: Is there maybe any other way to find out if the user did press stop in VLC player?So for example,if I play something in VLC on Win7 and go with the mouse on the VLC player icon in the bottom taskbar then it pop ups a small window what does show me also the VLC player (you know what I mean) and inside this little window it does also show a play / pause / stop etc buttons I can use.So how does Windows that and find this functions + hooking them etc? So maybe anyone of you have any another ideas how to find out if the stop button was pressed in VLC player. greetz
LCF-AT Posted April 11, 2017 Author Posted April 11, 2017 Hi raggy, just use a older PM topic from us and earlier so there you can PM me.Or does it now work for you to PM me there? greetz
LCF-AT Posted April 17, 2017 Author Posted April 17, 2017 Hi again, got another problem with the pipes.Problem is that the bytes I do read from internet (video) are fast finished and then I do close the pipe also if the video what is shown in VLC is not finished yet.Lets say the video has a lenght of 10 seconds and after 2 seconds the bytes reading is finished and then the pipe gets closed etc.So how can I set a paramter to wait into pipe (keep running)?Anyway whether I use Named or Anonymous pipes. .repeat invoke recv, s, buffer, len, 0 mov BYTES, eax .............. invoke WriteFile, PIPEHANDLE_WRITE, buffer, BYTES, offset numberBytesWritten ,offset overlapped .............. .until BYTES == 0 Close / Cleanup code So after all bytes was written into the pipe I need to do anything like any wait operation etc so that the video keeps playing in VLC player so long till all bytes was played.You know what I mean right?I also tried to set a sleep API after until command with some seconds just to see whether its playing longer etc but also in this case isnt working.Also tried other wait APIs as WaitForSingleObject or WaitNamedPipe but dosent work.So has anyone of you any idea how to handle that problem? Thank you
atom0s Posted April 17, 2017 Posted April 17, 2017 Read up on how the pipe is created for blocking/non-blocking modes and such: https://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx As well as the wait API: https://msdn.microsoft.com/en-us/library/aa365800(v=vs.85).aspx 1
LCF-AT Posted April 17, 2017 Author Posted April 17, 2017 Hi again, thanks for your answer but I tried this already without success.The WaitNamedPipe function dosent return anymore if I use flag NMPWAIT_WAIT_FOREVER also if the playing bytes are finished or if I close the player.If I use default timeout flag then it comes back right after video did start.Also the video does only start if I disconnect the pipe after all bytes was received from recv API and written into pipe.If I use DisconnectNamedPipe (Entire video gets played till end) and I use right after that function the PeekNamedPipe API to get infos about this pipe then I get the error ERROR_BAD_PIPE also if I close the player so the error keeps same and dosent change.If I close the handle to pipe = video runs complete but after this I cant check anymore anything whether the pipe is still playing or not to let terminate the player prrocess. you know what I mean? .repeat invoke recv, s, buffer, len, 0 mov BYTES, eax .............. invoke WriteFile, PIPEHANDLE_WRITE, buffer, BYTES, offset numberBytesWritten ,offset overlapped .............. .until BYTES == 0 invoke CloseHandle,PIPEHANDLE_WRITE // Now Here I need any checks / waits before calling terminate // A check whether video still runs or not or if finished // Wait so long here and then go on to terminate / cleanup invoke TerminateProcess, pinfo.hProcess, NULL // Terminate player Close / Cleanup code greetz
LCF-AT Posted April 18, 2017 Author Posted April 18, 2017 Hi again, ok I have testet go on and did created now a another thread to check the player window titel and if this does match then I do terminate the player.So its working so far on first tests but again there is a little problem with the FindWindow / Ex APIs.So the API only does work for top-level windows (only if player is on top / selected).Now I tried to find another method and wrote this new thread code... VLC_RUNCHECK proc A:DWORD,B:DWORD,BB:DWORD,CC:DWORD local PID:DWORD local ExitCode:DWORD local class [512]:BYTE mov edi,CC ASSUME edi:PTR VLC_EXIT A1: invoke Sleep,1000 invoke GetExitCodeProcess,[edi].hProcess,addr ExitCode .if ExitCode == STILL_ACTIVE .else invoke CloseHandle,[edi].hThread invoke TerminateProcess,[edi].hProcess,NULL invoke VirtualFree,[edi].section,0,MEM_RELEASE ret .endif invoke GetTopWindow,NULL .while eax != 0h mov esi,eax invoke GetWindowThreadProcessId,esi,addr PID mov eax, PID .if eax == [edi].dwProcessId invoke GetWindowText,esi,Addr class,sizeof class .if eax != 0h invoke lstrcmpi,addr class,chr$("VLC media player") .if eax == 0h nop invoke CloseHandle,[edi].hThread invoke TerminateProcess,[edi].hProcess,NULL invoke VirtualFree,[edi].section,0,MEM_RELEASE ret .endif .endif .endif invoke GetWindow,esi,GW_HWNDNEXT .endw jmp A1 VLC_RUNCHECK endp ...seems to work so far. Should be ok or what do you think?Now the player does close if video is finished or if I press stop button in VLC. greetz
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now