Camera video communication on the network

xiaoxiao2021-03-06  59

Article Category: Internet, video, chat Author: Liao Long Branch (posted please indicate the original author)

In the case: Maybe when writing this article, there are many friends who are being made similar to QQ. Here, I will write my experience and code to share with everyone, don't laugh at me. ! After reading this article, you can also be a simple online video communication software. If your home is online, you can communicate visual communications in the company and family, more cool, don't give the phone.

This example is the simple old technology (VFW), developed relatively simple, the following is the delphi code, you need to join the vfw.pas file first, no file you can find it online. The author starts programming from Delphi4. In fact, Delphi can do a lot of things, just too many Delphi programmers do not have special technologies and ideas, without surpassing themselves, Delphi is just a development tool, code ideas are the essence of design. Let us explain together:

At the beginning of the program, you need to create a camera handle with CapCreateCaptureWindow, capwnd: = CapCreateCaptureWindow ('preview window ", ws_visible or ws_child, 0, 0, 320, 240, prevwnd, 1); in the back parameters: prevwnd represents the handle of the preview window, You can specify a PANEL handle; 320 and 240 represent the length of the window. If CAPWND = 0 THEN EXIT; CAPDRIVERCONNECT (CAPWND, 0); // Connect the camera device

CAPDLGVIDEOFORMAT (CAPWND); / / Displays the Video Settings dialog box, performs the size of the video, the number of color bits, and the like. CapGetVideoFormat (CapWnd, @ bmpinInfo, sizeof (bitmapInfo)); // Number of video image data heads, need to be used when compressed back

CAPPREVIEWRATE (CAPWND, 33); // Sets the frequency of the preview video, 33 represents the second 30 frames. CAPPREVIEW (CAPWND, TRUE);

CapsetCallback (CapWnd, FrameCallback); InitCaptureParams; the last sentence is to set the video compression parameter, and will be described later. Where CapSetCallbackonFrame (CapWnd, FrameCallback) is a callback function for setting each frame of video data, we can transfer video data from the callback through the network, so that the core of video chat is realized.

The format of the callback function is as follows:

function FrameCallBack (hWnd: HWND; lpVHdr: PVIDEOHDR): DWORD; stdcall; var bKeyFrame: BOOL; Buf: PBYTE; VideoData: TVIDEO_DATA; OutActSize: dword; i: integer; begin OutActSize: = BmpInInfo.bmiHeader.biSizeImage; Buf: = IcseqcompressFrame (@ Capvar, 0, LPVHDR.LPDATA, @ bkeyframe, @ outactsize); // Here, OutactSize represents compressed video data size // Form1.Label3.caption: = 'compressed size:' INTOSTR (Outactsize) // I use the UDP mode because the UDP packet size limit, so I control the size of the data, the exceriving data will lose IF (Outactsize <= sizeof (videodata.buf)) The begin ZeromeMory (@videodata, SIZEOF (TVIDEO_DATA)); // Record is a keyframe videodata.bkeyframe: = bkeyframe;

CopyMemory (@ videodata.buf, buf, outactsize); VideoData.samplenum: = SampleNum; // We can record the number of frames, you can do extended videodata.bufsize: = outactsize; // record data size, transfer // Here you can use your favorite network to transfer video data, //cc1.sendbuffer (VideoData, SizeOf (Tvideo_Data);

INC; End; Result: = 0;

Among them, the PVIdeOHDR type can see its definition from the VFW: tvideohdr = Record LPDATA: PBYTE; // Video Data Buffer DWBufferLength: DWORD; // Data Buffer length DWBYTESUSED: DWORD; DWTIMECAPTURED: DWORD; // Time Length (ms) DWuser : Dword; dwflags: dword; dwreserved: array [0..3] of dword; end; in the callback function, only the video function: ICSEQCompressFrame, you can see that this function passes the Capvar parameter, this parameter is made by us previously seen InitCaptureParams generating function, code to implement the following: function InitCaptureParams: boolean; begin result: = False; // initialize CapVar zeromemory (@ CapVar, sizeof (TCOMPVARS)); CapVar.cbSize: = sizeof (CapVar); / / Must specify CBSIZE for TcompVars structure size Capvar.dwflags: = ICMF_COMPVARS_VALID;

Capvar.cbState: = 0; // fcchandler represents the compressed encoding type, we use the DivX encoder Capvar.fcchandler: = mmiofourcc ('d', 'i', 'v', 'x'); Capvar.fcctype : = ICTYPE_VIDEO;

// Official connection encoder Capvar.hic: = iCopen (ICTYPE_VIDEO, CAPVAR.FCCHANDLER, ICMODE_COMPRESS); if (Capvar.hic> 0) THEN Begin

OutFormatSize: = ICCompressGetFormatSize (CapVar.hic, @ BmpInInfo.bmiHeader); getmem (BmpOutInfo, OutFormatSize); // we can get compressed image outgoing head BmpOutInfo ICCompressGetFormat (CapVar.hic, @ BmpInInfo.bmiHeader obtained by BmpInInfo initialization , @ BmpOutInfo ^ .bmiHeader); OutBufferSize: = ICCompressGetSize (CapVar.hic, @ BmpInInfo.bmiHeader, @ BmpOutInfo ^ .bmiHeader); ICSeqCompressFrameStart (@CapVar, @BmpInInfo); result: = True; end else begin ShowMsg ( 'please First install video compression encoder '); exit; end end; after use, if you want to disconnect the encoder connection, this is called: if (Capvar.hic> 0) The begin IcseqcompressFrameEnd (@capvar); iccompressorfree (@capvar); @capvar); @capvar IcClose (Capvar.hic); end;

As a result, the server camera data capture is complete, then the client is the video data decompression? This problem is of course still resolved through the IC function, but you must first transfer BMPoutInfo and CAPVAR on the server to the client. Next, let's take a look at the client's image display process: // first use the obtained CAPVAR to connect video encoder Capvar.hic: = iCopen (Capvar.fcctype, Capvar.fcchandler, ICMODE_DECOMPRESS); // After success, Come BMPoutInfo as the client's BmpinInfo to get the image header BMPoutInfo of decompression output

Outformatsize: = icdecompressgetformatsize (Capvar.hic, @ BmpinInInfo.Bmihead); getmem (bmpoutinfo, outformatsize); zeromeMory (bmpoutInfo, outformatsize);

Icdecompressgetformat (Capvar.hic, @ bmpininfo.bmiheader, @ bmpoutinfo ^ .bmiheader);

Outbuffersize: = bmpoutInfo ^ .bmiheader.bisizeImage; getMem (Outbuffer, Outbuffers);

ZeromeMory (Outbuffer, Outbuffers); IcdecompressBegin (Capvar.hic, @ bmpininfo.bmiheader, @ bmpoutinfo ^ .bmihead);

Finally, of course, the decompression process of video data

if VIDEO_DATA.bKeyFrame then Result: = ICDecompress (CapVar.hic, 0, @ BmpInInfo, @ VIDEO_DATA.Buf, @ BmpOutInfo.bmiHeader, OutBuffer) else Result: = ICDecompress (CapVar.hic, ICDECOMPRESS_NOTKEYFRAME, @ BmpInInfo, @ VIDEO_DATA.Buf , @ BmpOutInfo.bmiHeader, OutBuffer); if (Result = ICERR_OK) then begin SetDIBitsToDevice (Canvas.Handle, 0,0, bmptmp.Width, bmptmp.Height, 0,0,0, BmpOutInfo ^ .bmiHeader.biHeight, OutBuffer, BMPoutInfo ^, DIB_RGB_COLORS; END; This, the transferred video data varies directly to Canvas.Handle. I have also forgotten the server to turn off the camera, calling CAPDriverDisconnect (CapWnd) to OK.

The full text is OVER. Jasonke also said that this method is the Microsoft's old function, but it is very simple. I believe that the API can be developed, and there is of course DirectShow, this Need you to develop Filter, you have to understand several of Microsoft's interface, you can take a look at the DSHOWNETWORK example. This method also has a lot of C brothers in the painful implementation, thinking about DirectShow's function is really powerful, haha ​​ndg4289w.

500010000853650227136

转载请注明原文地址:https://www.9cbs.com/read-85125.html

New Post(0)