李娜多媒体网络通信技术

2026/1/27 1:33:48

3.4.2语音回放

相对录音而言,播放就简单多了,同样用的一个CWinThread对象CAudioPlay来实现,部分实现代码:

LRESULT CAudioPlay::OnWriteSoundData(WPARAM wParam, LPARAM lParam) { //

TRACE(\

MMRESULT mmResult = FALSE; char *p=NULL;

int length=(int) wParam;

if(Playing==FALSE) return FALSE; if(length<=0)

return FALSE;

WAVEHDR *lpHdr=new WAVEHDR; if(!lpHdr)

return FALSE;

p=new char [length]; if(!p) {delete lpHdr; return FALSE;}

ZeroMemory(lpHdr,sizeof(WAVEHDR)); ZeroMemory(p,length);

CopyMemory(p,(char*)lParam,length); lpHdr->lpData=p;

lpHdr->dwBufferLength = length;

mmResult = ::waveOutPrepareHeader(m_hPlay, lpHdr, sizeof(WAVEHDR)); //为回放设备准备内存块 if(mmResult){ delete lpHdr;delete p; return mmResult;}

mmResult = ::waveOutWrite(m_hPlay, lpHdr, sizeof(WAVEHDR));//写数据(放音) if(mmResult){delete lpHdr;delete p; return mmResult; }

m_Count++;

return MMSYSERR_NOERROR; }

3.5音视频发送与接收

视频采集采用AVICap从视频采集卡捕获视频图像,得到的是位图形式的视频帧,然后用Divx编码器进行压缩,压缩以后形成以帧为格式的Mpeg4流。通过Winsock实现压缩后的视频数据在局域网中的实时传输,接收完的数据交给Divx解码器,以帧的格式解压,最后实现视频显示。所以提出以帧为单位发送视频数据流。为了在接收端能够方便地提取出一帧,提出如表1所示的格式组建帧。完整的一帧由5个字段组成,各个字段的意义如下:帧开始标志:标志着一帧地开始,占用4个字节的空间;帧大小:表示整个帧的大小,包括5个字段的大小,占用4个字节的空间;帧编号:表示帧的顺序编号,占用4个字节的空间;帧类型:标志此帧是否是关键帧,占用1个字节的空间;帧数据:存放压缩后一帧的完整数据。

3.5.1音视频发送与接收模块流程图

音视频发送与接收模块流程图如图8所示。

图8 音视频发送与接收模块流程图

3.5.1音视频发送与接收代码

不妨假设创建的线程名为sendThread,发送代码如下: while(1){

isOK=true; //准备就绪

SuspendThread(sendThread); //挂起线程

isOK=false; //线程正在发送数据 int length=frameLength; //待发数据长度 if(length<50000) {//判断数据是否正常 int n=0;

int sendCount=0; while(length>0) {

n=send(sock,(char*)imageBuf+sendCount,length,0); //发送数据, //imageBuf是指针,指向待发数据帧

if(n==SOCKET_ERROR) //网络出现异常,则退出线程 break; length-=n; sendCount+=n;}} }

接收端创建一个线程专门用来执行数据接收。不妨假设线程名为recThread,核心代码实现如下:

while(temp!=SOCKET_ERROR){

if(!isStart) {//帧数据是否开始,true表示开始 if(endNum>3) //endNum纪录当前接收未处理的数据 endNum=0;

temp=recv(clisock,(char*)(recBuf+endNum),1000,0);//从缓冲区读取数据 startPos=serchStr(temp+endNum); //查找帧开始标志 if(startPos!=-1) { isStart=true;

endNum=temp+endNum-startPos-4;

memcpy(imageBuf,recBuf+startPos+4,endNum); //保存帧数据} else{

memcpy(recBuf,recBuf+temp+endNum-3,3);//保存最后三个字节的数据 endNum=3;} }

else{

if(endNum<4) {//判定紧跟开始标志的数据,如果小于4表示不能获得帧大小 temp=recv(clisock,(char*)(recBuf),1000,0); //读入数据 memcpy(imageBuf+endNum,recBuf,temp);//保存数据 endNum+=temp; if(endNum<4) continue;

frameSize= *((int*)imageBuf);//获得帧大小

if(frameSize<500 || frameSize>50000) {//异常处理(帧大小非法) isStart = false; //丢弃数据重新查找帧开始标志 endNum = 0; continue;}

frameSize-=endNum+4;} else{

while(frameSize>0&&temp!=SOCKET_ERROR) {//获得完整帧的剩余数据temp=recv(clisock,(char*)(imageBuf+endNum),frameSize,0); endNum+=temp; frameSize-=temp;}

if(frameSize<=0) {//帧结束置位,解压 isStart=false; endNum=0;

deCompress();//判断数据的有效性,调用ICDecompress进行解压}}} }


李娜多媒体网络通信技术.doc 将本文的Word文档下载到电脑
搜索更多关于: 李娜多媒体网络通信技术 的文档
相关推荐
相关阅读
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 10

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219