C#广域网视频的压缩和传输
用C#开发了一个类似QQ的广域网聊天软件,就差视频了。
视频压缩用的是VFW技术,有缓冲区,
网络传输用的是UDP协议(可以穿透NAT)。
现在视频有些花,就像马赛克一样,色块经常丢失。问题可能出现在哪些地方?

解决方案 »

  1.   

    udp丢点东西很正常
    你在局域网测试应该不会吧?
    首先udp不保证数据是不是一定发到了接收方
      

  2.   

    .net 关于这样深入的资料太少了,楼住是从哪里学的 “频的压缩和传输”技术?
      

  3.   

    楼主,我现在只能捕捉到摄像头视频,可不知到该如何压缩传输,楼主能发一份压缩传输部分的代码吗
    [email protected] 
    谢了先
      

  4.   

    to: lgwwwusing System;
    using System.Runtime.InteropServices;namespace VideoPreview.Utilities
    {
        public class CCodec
        {
            private int hic;
            //private IntPtr hic;
            private COMPVARS cp;
            private BITMAPINFO cbiIn;
            private BITMAPINFO cbiOut;        private int dehic;
            //private IntPtr dehic;
            private COMPVARS decp;
            private BITMAPINFO decbiIn;
            private BITMAPINFO decbiOut;        public bool InitCompress(BITMAPINFOHEADER bi)
            {
                this.cp = new COMPVARS();
                cp.cbSize = Marshal.SizeOf(this.cp);
                cp.dwFlags = 1; // ICMF_COMPVAES_VALID
                cp.fccHandler = 2021026148;
                cp.fccType = FOURCC.ICTYPE_VIDEO;            cp.lKey = 15;
                cp.lQ = 10000;            this.hic = ICOpen(cp.fccType, cp.fccHandler, ICMODE.ICMODE_COMPRESS | ICMODE.ICMODE_DECOMPRESS);
                if (this.hic != 0)
                {
                    cp.hic = this.hic;
                    cbiIn = new BITMAPINFO();
                    cbiIn.bmiHeader = bi;
                    if (ICSendMessage(this.hic, ICM_COMPRESS_GET_FORMAT, ref this.cbiIn, ref this.cbiOut) == ICERR_OK)
                    {
                        return ICSeqCompressFrameStart(ref this.cp, ref this.cbiIn);
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }        public byte[] CPProcess(byte[] data)
            {
                if (this.hic == 0)
                {
                    return null;
                }
                bool key = false;
                int size = 0;
                try
                {
                    lock (data)
                    {
                        IntPtr source = ICSeqCompressFrame(
                            ref this.cp,
                            0,
                            data,
                            ref key,
                            ref size);
                        if (size > 0)
                        {
                            byte[] cpdata = new byte[size];
                            try
                            {
                                Marshal.Copy(source, cpdata, 0, size);
                            }
                            catch
                            {
                                //System.Windows.Forms.MessageBox.Show("Data array over flow!", "CompressframeError", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
                            }
                            return cpdata;
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    //System.Windows.Forms.MessageBox.Show("Compress Exception : " + ex.Message);
                }
                return null;
            }        public bool InitDecompress()
            {
                if (this.cp.hic != 0)
                {
                    this.decp = this.cp;
                    this.dehic = this.hic; // this.cp.hic;
                }
                else
                {
                    return false;
                }            //this.dehic = ICOpen(cp.fccType, cp.fccHandler, ICMODE.ICMODE_DECOMPRESS);            this.decbiIn = this.cbiOut;
                this.decbiOut = this.cbiIn;            if (this.dehic != 0)
                {
                    if (ICSendMessage(this.dehic, ICM_DECOMPRESS_BEGIN, ref this.decbiIn, ref this.decbiOut) == ICERR_OK)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }        public byte[] DECCPProcess(byte[] data)
            {
                if (this.dehic == 0)
                {
                    return null;
                }
                byte[] deccpdata = new byte[this.decbiOut.bmiHeader.biSizeImage];
                try
                {
                    if (ICDecompress(this.dehic, 0, ref this.decbiIn.bmiHeader, data, ref this.decbiOut.bmiHeader, deccpdata) != ICERR_OK)
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    //System.Windows.Forms.MessageBox.Show("Decompress Exception : " + ex.Message);
                }
                return deccpdata;
            }        public void CCodecClose()
            {
                try
                {
                    if (this.hic != 0)
                    {
                        try
                        {
                            ICSeqCompressFrameEnd(ref this.cp);
                        }
                        catch { }
                        ICClose(this.hic);
                    }
                    if (this.dehic != 0)
                    {
                        try
                        {
                            ICSendMessage(hic, ICM_USER + 14, 0, 0);
                        }
                        catch { }
                        ICClose(this.dehic);
                    }
                }
                catch { }
            }
      

  5.   


            #region
            [DllImport("MSVFW32.dll")]
            public static extern int ICCompressGetFormat(
                //int hic,
                IntPtr hic,
                ref BITMAPINFO lpbiInput,
                ref BITMAPINFO lpbiOutput
                );        [DllImport("MSVFW32.dll")]
            public static extern int ICDecompressBegin(
                //int hic,
                IntPtr hic,
                ref BITMAPINFO lpbiInput,
                ref BITMAPINFO lpbiOutput
                );        [DllImport("VFW32.dll")]
            public static extern int ICDecompressGetFormat(
                //int hic,
                IntPtr hic,
                ref BITMAPINFO lpbiInput,
                ref BITMAPINFO lpbiOutput
                );        [DllImport("MSVFW32.dll")]
            public static extern void ICSeqCompressFrameEnd(ref COMPVARS pc);        [DllImport("MSVFW32.dll")]
            public static extern int ICCompressGetFormatSize(
                int hic,
                ref BITMAPINFO lpbiInput
                );        [DllImport("MSVFW32.dll")]
            public static extern bool ICSeqCompressFrameStart(
                ref COMPVARS pc,
                //ref BITMAPINFO lpbiIn
                ref BITMAPINFO lpbiIn
                );        [DllImport("MSVFW32.dll")]
            public static extern IntPtr ICSeqCompressFrame(
                ref COMPVARS pc,
                uint uiFlags,
                byte[] lpBits,
                ref bool pfKey,
                //ref ushort pfKey,
                //ref long plSize
                ref int plSize
                );        [DllImport("MSVFW32.dll", CharSet = CharSet.Ansi)]
            public static extern int ICGetInfo(
                int hic,
                ICINFO lpicinfo,
                int cb
                );        [DllImport("MSVFW32.dll")]
            public static extern bool ICCompressorChoose(
                IntPtr hwnd,
                int uiFlags,
                //int pvIn,
                //int lpData,
                IntPtr pvIn,
                IntPtr lpData,
                ref COMPVARS pc,
                string lpszTitle
                );        [DllImport("MSVFW32.dll")]
            public static extern int ICLocate(
                int fccType,
                int fccHandler,
                ref BITMAPINFOHEADER lpbiIn,
                ref BITMAPINFOHEADER lpbiOut,
                short wFlags
                );        [DllImport("MSVFW32.dll"), PreserveSig]
            public static extern int ICOpen(uint fccType, uint fccHandler, ICMODE wMode);
            //public static extern IntPtr ICOpen(uint fccType, uint fccHandler, uint wmode); // ICMODE wMode);        [DllImport("MSVFW32.dll"), PreserveSig]
            public static extern int ICDecompressOpen(
                int fccType,
                int fccHandler,
                ref BITMAPINFOHEADER lpbiIn,
                ref BITMAPINFOHEADER lpbiOut
                );        [DllImport("MSVFW32.dll")]
            public static extern int ICClose(int hic);        [DllImport("MSVFW32.dll")]
            public static extern int ICCompress(
                int hic,
                int dwFlags,        // flags
                ref BITMAPINFOHEADER lpbiOutput,     // output format
                IntPtr lpData,         // output data
                ref BITMAPINFOHEADER lpbiInput,      // format of frame to compress
                IntPtr lpBits,         // frame data to compress
                int lpckid,         // ckid for data in AVI file
                int lpdwFlags,      // flags in the AVI index.
                int lFrameNum,      // frame number of seq.
                int dwFrameSize,    // reqested size in bytes. (if non zero)
                int dwQuality,      // quality within one frame
                int lpbiPrev,       // format of previous frame
                int lpPrev          // previous frame
                );        [DllImport("MSVFW32.dll")]
            public static extern int ICDecompress(
                int hic,
                //IntPtr hic,
                //int dwFlags,
                uint dwFlags,
                ref BITMAPINFOHEADER lpbiFormat,
                byte[] lpData,
                ref BITMAPINFOHEADER lpbi,
                byte[] lpBits
                );        [DllImport("MSVFW32.dll")]
            public static extern int ICSendMessage(int hic, int msg, ref BITMAPINFO dw1, ref BITMAPINFO dw2);        [DllImport("MSVFW32.dll")]
            public static extern int ICSendMessage(int hic, int msg, int dw1, int dw2);        [DllImport("MSVFW32.dll")]
            public static extern int ICSendMessage(int hic, int msg, ICINFO dw1, int dw2);
            public static readonly int DRV_USER = 0x4000;
            public static readonly int ICM_USER = (DRV_USER + 0x0000);
            public static readonly int ICM_COMPRESS_BEGIN = (ICM_USER + 7);    // begin a series of compress calls.
            public static readonly int ICM_COMPRESS = (ICM_USER + 8);   // compress a frame
            public static readonly int ICM_COMPRESS_END = (ICM_USER + 9);   // end of a series of compress calls.
            public static readonly int ICM_COMPRESS_GET_FORMAT = (ICM_USER + 4);
            public static readonly int ICM_DECOMPRESS_BEGIN = (ICM_USER + 12);   // start a series of decompress calls
            public static readonly int ICM_DECOMPRESS = (ICM_USER + 13);   // decompress a frame
            public static readonly int ICM_DECOMPRESS_END = (ICM_USER + 14);        public static readonly int ICERR_OK = 0x0;
            #endregion
        }
    }其实也没什么,用的是Divx编码器。
      

  6.   

    to : purple_tide
      这个我当然知道。我在接受端设置了缓冲和帧重排序,仔细看了看好像还是传输的问题。
    今天改了一个参数效果比以前好多了,但摄像头捕获禁止的物体时仍然会有花屏现象。
      

  7.   

    也没什么,都是调用的Windows的API.
      

  8.   

    看下cp.fccType, cp.fccHandler是否对应,或者系统中是否有你需要的编码器。上面的代码中用的是Divx编码器
      

  9.   

    楼主的这份代码在网上挺多的,我也看了这份代码,我觉得这个代码不行,上面用的DivX编码器,如果客户端没有安装Divx编码器,根本就实现不了压缩,所以必须解决聊天客户端检测目标机器是否安装了相应解码器,如果没有安装,自己得实现安装。
    再一个问题,我做了试验,即使安装了Divx解码器,压缩得到的数据有的也挺大的,自己还必须实现分包,包太大的话是不适合在广域网上传输的(视频传输一般用Udp传,大包在网络状况不好的情况下是会丢失的)。
      

  10.   

    我觉得这个不是问题,做一个安装包就可以了,如果不借助第三方压缩方式,你自己写就复杂多了。所以你应该学会利用资源,做个安装包,先安装divx播放代码就可以了。
      

  11.   

    确实,那个hic为0的就是没有编码包
      

  12.   

    同样问题,hic为零,数据得不到,
      

  13.   

    同样问题,hic为零,数据得不到,
      

  14.   

    确实是解码的原因 下载一个叫mpeg4x解码器安装即可
      

  15.   

    ffdshow MPEG-4 Video Decoder
    需要下载这个解码器才能工作。
    http://www.onlinedown.net/soft/5636.htm
      

  16.   

    ffdshow MPEG-4 Video Decoder
    需要下载这个解码器才能工作。
    http://www.onlinedown.net/soft/5636.htm