C#广域网视频的压缩和传输

openwhitewater 2008-05-21 09:56:13
C#广域网视频的压缩和传输
用C#开发了一个类似QQ的广域网聊天软件,就差视频了。
视频压缩用的是VFW技术,有缓冲区,
网络传输用的是UDP协议(可以穿透NAT)。
现在视频有些花,就像马赛克一样,色块经常丢失。问题可能出现在哪些地方?
...全文
1175 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
hamilton_chz 2012-04-03
  • 打赏
  • 举报
回复
ffdshow MPEG-4 Video Decoder
需要下载这个解码器才能工作。
http://www.onlinedown.net/soft/5636.htm
hamilton_chz 2012-04-03
  • 打赏
  • 举报
回复
ffdshow MPEG-4 Video Decoder
需要下载这个解码器才能工作。
http://www.onlinedown.net/soft/5636.htm
之握成 2011-12-26
  • 打赏
  • 举报
回复
忘了留邮箱:jiyong012@163.com
之握成 2011-12-26
  • 打赏
  • 举报
回复
楼主,我也正在学习视频压缩这一块,你能把代码发给我一下吗?
QQ1181147858 2011-03-15
  • 打赏
  • 举报
回复
确实是解码的原因 下载一个叫mpeg4x解码器安装即可
q464530237 2011-03-11
  • 打赏
  • 举报
回复
同样问题,hic为零,数据得不到,
  • 打赏
  • 举报
回复
同样问题,hic为零,数据得不到,
wangbin_CSDN 2011-01-16
  • 打赏
  • 举报
回复
确实,那个hic为0的就是没有编码包
峰子2017 2010-07-29
  • 打赏
  • 举报
回复
正需要这个
srxljl 2009-09-24
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 mayang_117 的回复:]
楼主的这份代码在网上挺多的,我也看了这份代码,我觉得这个代码不行,上面用的DivX编码器,如果客户端没有安装Divx编码器,根本就实现不了压缩,所以必须解决聊天客户端检测目标机器是否安装了相应解码器,如果没有安装,自己得实现安装。
再一个问题,我做了试验,即使安装了Divx解码器,压缩得到的数据有的也挺大的,自己还必须实现分包,包太大的话是不适合在广域网上传输的(视频传输一般用Udp传,大包在网络状况不好的情况下是会丢失的)。
[/Quote]

抱歉啊,15楼中,我是对14楼说的,点引用时点错了。
srxljl 2009-09-24
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 openwhitewater 的回复:]
看下cp.fccType, cp.fccHandler是否对应,或者系统中是否有你需要的编码器。上面的代码中用的是Divx编码器
[/Quote]
我觉得这个不是问题,做一个安装包就可以了,如果不借助第三方压缩方式,你自己写就复杂多了。所以你应该学会利用资源,做个安装包,先安装divx播放代码就可以了。
mayang_117 2008-10-07
  • 打赏
  • 举报
回复
楼主的这份代码在网上挺多的,我也看了这份代码,我觉得这个代码不行,上面用的DivX编码器,如果客户端没有安装Divx编码器,根本就实现不了压缩,所以必须解决聊天客户端检测目标机器是否安装了相应解码器,如果没有安装,自己得实现安装。
再一个问题,我做了试验,即使安装了Divx解码器,压缩得到的数据有的也挺大的,自己还必须实现分包,包太大的话是不适合在广域网上传输的(视频传输一般用Udp传,大包在网络状况不好的情况下是会丢失的)。
openwhitewater 2008-07-09
  • 打赏
  • 举报
回复
看下cp.fccType, cp.fccHandler是否对应,或者系统中是否有你需要的编码器。上面的代码中用的是Divx编码器
游鱼_ 2008-07-07
  • 打赏
  • 举报
回复
帮顶!

顺便问下楼主:
为何我的这句this.hic = ICOpen(cp.fccType, cp.fccHandler, ICMODE.ICMODE_COMPRESS ¦ ICMODE.ICMODE_DECOMPRESS);
老是反回为0呀!很是郁闷中!
openwhitewater 2008-06-06
  • 打赏
  • 举报
回复
也没什么,都是调用的Windows的API.
wdgphc 2008-06-06
  • 打赏
  • 举报
回复
狂顶,我也正需要这个
openwhitewater 2008-06-06
  • 打赏
  • 举报
回复
to : purple_tide
这个我当然知道。我在接受端设置了缓冲和帧重排序,仔细看了看好像还是传输的问题。
今天改了一个参数效果比以前好多了,但摄像头捕获禁止的物体时仍然会有花屏现象。
openwhitewater 2008-06-06
  • 打赏
  • 举报
回复

#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编码器。
openwhitewater 2008-06-06
  • 打赏
  • 举报
回复
to: lgwww

using 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 { }
}

lgwww 2008-05-21
  • 打赏
  • 举报
回复
楼主,我现在只能捕捉到摄像头视频,可不知到该如何压缩传输,楼主能发一份压缩传输部分的代码吗
game_wang@sina.com
谢了先
加载更多回复(5)
OurMsg2014是基于.net 4.0框架C#语言编写的即时消息软件(服务器和客户端)。开发初衷是面向企业级的即时消息应用,可集成企业OA等管理信息系统。服务器网络框架采用LumiSoft.Net,支持上百万用户的连接,1台服务器可支持两万用户同时在线。服务器端数据库采用SQLite for .net4版本,并发加入单线程队列写数据库,多线程读数据库(用户规模在万人以内完全能够应对),如果想要使用SQL Server、Oracle、My sql等数据库,请自行开发,数据结构参见服务器数据库,目录:Server\Bin\OurMsgServerDB.s3db,在OurMsgServer.Server代码中,重写数据库操作事件代码的数据库访问方法即可简单实现。客户端采用SQLite数据库保存用户信息,聊天信息等,和老版本结构一样。 OurMsg可部署在广域网或局域网上。作者水平有限,抛砖引玉,还望高手批评指正!!! ourmsg 基本功能: 1、支持文本及动画表情聊天、支持离线消息。 2、支持群组聊天,支持群发通知、消息、短信等功能。 3、支持P2P文件传输、支持离线文件发送功能。 4、支持远程协助(任何屏幕大小分辨率),同一局域网内提供高清windows桌面图片的编码传输,互联网图像会经压缩,质量稍差。 5、支持P2P RTP/RTCP音视频传输,1路音频占用带宽1K-3K,1路视频占用带宽25KB左右。在下一个版本中将提供多人视频功能。保障ADSL低带宽用户能顺畅使用10路视频会议服务。 6、支持开发人员随意扩展或增加新功能(自己发挥自己的想像吧)。 7、客户端和服务端均支持所有.net4.0框架能安装的windows操作系统(X32/X64),即XP、Vista、win7、win8、win2003server、win2008server等。 8、UTF8编码的数据交换,支持多国语言。 说明:文件传输、远程协助、音频、视频的底层传输采用的是UDP P2P,提供了支持任何网络类型的NAT穿越(最坏情况下采取类TURN方式的NAT穿越方法,可穿越任何NAT,包括对称型NAT),音频、视频编码为一路,采用RTP/RTCP Over UDP P2P,最大限度保障同步传输

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧