小弟我已下载安装那divx4.dll,但不知如何在开发中使用,望使用过divx开发过的大虾指点(wyly)

likevclinux 2002-07-31 11:25:44
如题
...全文
43 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
likevclinux 2002-07-31
  • 打赏
  • 举报
回复
谢谢你,看来我只有痛过vfw那!
wyly 2002-07-31
  • 打赏
  • 举报
回复
用divx两种方法。
1 是直接调用dll,比较麻烦。可以看 divx 自己的文档。
2 是通过vfw来调用,比较简单,具体看看vfw的文档。
我不在 widnows下做的,所以无法提供例子。
dimcat 2002-07-31
  • 打赏
  • 举报
回复
To likevclinux(流浪的小狗) :

能不能把你用VC做的这个程序mail给我一份,让我学学。太感谢聊。

dimcat@sohu.com
wyly 2002-07-31
  • 打赏
  • 举报
回复
呵呵呵,怎么这么巧。
呵呵,对了,你看到我里面的isBig变量没有?
这个程序可以解两种尺寸,小尺寸可以放大。
likevclinux 2002-07-31
  • 打赏
  • 举报
回复
to wyly() ,我刚用vc写了个,压缩服务端,不过有那你这个bcb的我就不用在转bcb那,给你磕头那!
明天结帐,主要是让更多的人学习!
wyly 2002-07-31
  • 打赏
  • 举报
回复

bool ProcessUdpMessage(tagMSG msg)
{
//主程序发来的消息
switch(msg.wParam)
{
case THREAD_QUIT:
return true;

case UDP_START_WATCH: // 通知机顶盒停止报警
{
ICDecompressEnd(hic);
InitDecoder(isBig);
byte message = UDP_START_WATCH;
if (sendto(s,&message,1,0,(SOCKADDR *)&(to),sizeof(to))==SOCKET_ERROR)
ShowMessage("发送错误!");

break;

}

case UDP_STOP_WATCH: // 通知机顶盒停止报警
{
ICDecompressEnd(hic);
byte message = UDP_STOP_WATCH;
if (sendto(s,&message,1,0,(SOCKADDR *)&(to),sizeof(to))==SOCKET_ERROR)
ShowMessage("发送错误!");
break;
}

case UDP_CHANGE_CHANNEL: // 通知机顶盒切换通道
{
byte message[] = {UDP_CHANGE_CHANNEL,(byte)msg.lParam};
if (sendto(s,&message[0],2,0,(SOCKADDR *)&(to),sizeof(to))==SOCKET_ERROR)
ShowMessage("发送错误!");
break;
}

case UDP_CHANGE_CONFIG:
{
byte message[] = {UDP_CHANGE_CONFIG,(byte)msg.lParam};
if (sendto(s,&message[0],2,0,(SOCKADDR *)&(to),sizeof(to))==SOCKET_ERROR)
ShowMessage("发送错误!");
if (msg.lParam==0)
isBig = true;
else
isBig = false;

break;
}
}
return false;
}


unsigned long _stdcall ThreadFunc(void* p)
{
// 各种变量
//------------------------------------------
tagMSG msg;

SOCKADDR_IN local,from;
bufferPoint = 0;

pBuffer = new byte[64*1024*1024];

timeval timeOut = {0,0};

int addrlen = sizeof(from);
int readLen = 0;
int bitRate = 0;
startLocation = -1;
isBig = true;

unsigned int lastTime = GetTickCount();
unsigned int nowTime, dTime;

hThreadMutex = OpenMutex(SYNCHRONIZE,false,"mutex");

PeekMessage(&msg,0,UDP_MESSAGE,UDP_MESSAGE,PM_NOREMOVE);

//--------------------------------------------


//初始化解码器
hic = ICOpen(ICTYPE_VIDEO, mmioFOURCC('D','I','V','X'), ICMODE_FASTCOMPRESS);
if (hic==0)
{
ShowMessage("初始化VFW错误!");
return 1;
}

//初始化 UDP
//----------------------------------------------------------------
WSADATA wsd;
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
ShowError("打开WinSock 2.2 出错!",0);
return 0;
}

s = WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED);

if (s==INVALID_SOCKET)
{
ShowError("创建",WSAGetLastError());
return 0;
}

to.sin_family = AF_INET;
to.sin_port = htons(10000);
to.sin_addr.s_addr = inet_addr("192.168.1.1");

local.sin_family = AF_INET;
local.sin_port = htons(10000);
local.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s,(sockaddr *)&local,sizeof(local))==SOCKET_ERROR)
{
ShowError("绑定",WSAGetLastError());
return 0;
}
//-----------------------------------------------------------------

fd_set* readFds = new fd_set;
fd_set* writeFds = new fd_set;

int f = FileCreate( "test.mp4" );

// 死循环
while(true)
{
//检查可收发数据
FD_ZERO(readFds);
FD_SET(s,readFds);
FD_ZERO(writeFds);
FD_SET(s,writeFds);

if (select(0,readFds,writeFds,NULL,&timeOut)>0)
{
//检查是否有数据可读
if(FD_ISSET(s,readFds))
{
if (bufferPoint>64000000)
bufferPoint = 0;

readLen = recvfrom(s,pBuffer+bufferPoint,2048,0,(SOCKADDR *)&from,&addrlen);

// FileWrite(f,pBuffer+bufferPoint,readLen);
//发UDP收错误消息
if (readLen==SOCKET_ERROR)
{
continue;
}

bitRate = bitRate + readLen;
bufferPoint = bufferPoint + readLen;
if (ProcessUdpReceive())
ProcessUdpReceive();
}
}

//检查消息
if(PeekMessage(&msg,0,UDP_MESSAGE,UDP_MESSAGE,PM_NOREMOVE))
{
GetMessage(&msg,0,UDP_MESSAGE,UDP_MESSAGE);
if (ProcessUdpMessage(msg))
break;
}


nowTime = GetTickCount();
if (nowTime < lastTime)
dTime = nowTime + 0xffffffff - lastTime;
else
dTime = nowTime - lastTime;

if (dTime >= 2000)
{
PostMessage(hForm,UDP_MESSAGE,SHOW_BITRATE,bitRate*1024/(dTime*125));
PostMessage(hForm,UDP_MESSAGE,SHOW_FRAMES,frames*1000/dTime);
bitRate = 0;
frames = 0;
lastTime = GetTickCount();
}

Sleep(5);
}

// 退出线程的操作

CloseHandle(hThreadMutex);

delete pBuffer;
closesocket(s);
delete readFds;
delete writeFds;
FileClose(f);
return 0;
}

wyly 2002-07-31
  • 打赏
  • 举报
回复
我临时用cbuilder写了一个vfw解码的,如下。编码类推
功能:多线程 UDP接收视频播放。还带一个线性插值函数,可以放大图像2倍。

#include "thread.h"

#include <winsock2.h>
#include <vcl.h>
#include <vfw.h>

HANDLE hForm;
HANDLE hThreadMutex;
unsigned long threadId;
HANDLE hUdp;

byte* pBuffer ;
byte* pDisBuffer;

int bufferPoint;
int startLocation;

int frames;

SOCKADDR_IN to;
SOCKET s;

bool isBig;

//vfw
HIC hic = 0;
BITMAPINFO EncBiIn,EncBiOut;

//---------------------------------------------------------------------------
void X2(byte* source, byte* dest, int width, int height)
{
byte* p1,*p2,*p3;

// 隔点复制
for(int i=0;i<height;i++)
{
p1 = source+width*3*i;
p2 = dest+width*12*i;
for (int j=0;j<width;j++)
CopyMemory(p2+j*6,p1+j*3,3);
}


//行插
for (int i=0;i<height;i++)
{
p1 = dest+width*12*i;
for (int j=0;j<width-1;j++)
{
p1[j*6+3] = (p1[j*6] + p1[(j+1)*6])>>1;
p1[j*6+4] = (p1[j*6+1] + p1[j*6+7])>>1;
p1[j*6+5] = (p1[j*6+2] + p1[j*6+8])>>1;
}
}

//列插
for (int i=0;i<height-1;i++)
{
p1 = dest+width*12*i;
p2 = p1+width*6;
p3 = p1+width*12;
for (int j=0;j<width;j++)
{
p2[j*6] = (p1[j*6] + p3[j*6])>>1;
p2[j*6+1] = (p1[j*6+1] + p3[j*6+1])>>1;
p2[j*6+2] = (p1[j*6+2] + p3[j*6+2])>>1;
}
}

//双线性插值
for (int i=0;i<height-1;i++)
{
p1 = dest+width*12*i;
p2 = p1+width*6;
p3 = p1+width*12;
for (int j=0;j<width-1;j++)
{
p2[j*6+3] = (p1[j*6+3] + p2[j*6+1] + p2[j*6+6] + p3[j*6+3])>>2;
p2[j*6+4] = (p1[j*6+4] + p2[j*6+2] + p2[j*6+7] + p3[j*6+4])>>2;
p2[j*6+5] = (p1[j*6+5] + p2[j*6+3] + p2[j*6+8] + p3[j*6+5])>>2;
}
}

//最后一行和最后一列
CopyMemory(dest+width*6*(height*2-1),dest+width*6*(height*2-2),width*6);

for (int i=0;i<height-1;i++)
{
p1 = dest + width*6*(i+1);
CopyMemory(p1-3,p1-6,3);
}
}

void ShowError (char* errorString,int errorCode)
{
if (!errorCode)
MessageBox(0,errorString,"警告",MB_OK);
else
{
AnsiString eS = errorString;
eS = eS+"套接字错误:"+IntToStr(errorCode);
MessageBox(0,eS.c_str(),"警告",MB_OK);
}
}

void Decode(int location1, int location2)
{
static byte outBuffer[320*240*3];
static byte srcBuffer[65536];
static byte tempBuffer[320*240*3];

CopyMemory(&srcBuffer[0],pBuffer+location1,location2-location1);
EncBiOut.bmiHeader.biSizeImage = location2-location1;
ICDecompress(hic, 0, &EncBiOut.bmiHeader, pBuffer+location1, &EncBiIn.bmiHeader, &outBuffer[0]);

WaitForSingleObject(hThreadMutex,INFINITE);
if (isBig)
for (int i=0;i<240;i++)
CopyMemory(pDisBuffer+(239-i)*960,&outBuffer[i*960],960);
else
{
X2(&outBuffer[0],&tempBuffer[0],160,120);
for (int i=0;i<240;i++)
CopyMemory(pDisBuffer+(239-i)*960,&tempBuffer[i*960],960);
}

ReleaseMutex(hThreadMutex);
PostMessage(hForm,UDP_MESSAGE,DISPLAY,0);
frames++;
}

bool ProcessUdpReceive()
{
if (startLocation==-1)
{
for (int i=0;i<=bufferPoint-4;i++)
{
if( *((unsigned int *)(pBuffer+i))== 0x00010000 ||
*((unsigned int *)(pBuffer+i))== 0xb6010000)
{
startLocation = i;
return true;
}
}
}
else
{
for (int i=startLocation+20;i<=bufferPoint-4;i++)
{
if( *((unsigned int *)(pBuffer+i))== 0x01010000)
{
// 解码
Decode(startLocation,i);
bufferPoint = bufferPoint-i-4;
MoveMemory(pBuffer,pBuffer+i+4,bufferPoint);
startLocation = -1;
return false;
}
}
}

return false ;
}

void InitDecoder(int big)
{
EncBiIn.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
EncBiIn.bmiHeader.biCompression = BI_RGB;
EncBiIn.bmiHeader.biPlanes = 1;
EncBiIn.bmiHeader.biXPelsPerMeter = 0;
EncBiIn.bmiHeader.biYPelsPerMeter = 0;
EncBiIn.bmiHeader.biClrUsed = 0;
EncBiIn.bmiHeader.biClrImportant = 0;
EncBiIn.bmiHeader.biBitCount = 24;

if (big)
{
EncBiIn.bmiHeader.biWidth = 320;
EncBiIn.bmiHeader.biHeight = 240;
EncBiIn.bmiHeader.biSizeImage = 320*240*3;
}
else
{
EncBiIn.bmiHeader.biWidth = 160;
EncBiIn.bmiHeader.biHeight = 1200;
EncBiIn.bmiHeader.biSizeImage = 160*120*3;
}

ZeroMemory(&EncBiOut, sizeof(BITMAPINFO));

//设置压缩格式
EncBiOut.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
EncBiOut.bmiHeader.biCompression = mmioFOURCC('D','I','V','X');
EncBiOut.bmiHeader.biPlanes = 1;
EncBiOut.bmiHeader.biBitCount = 24;
EncBiOut.bmiHeader.biXPelsPerMeter = 0;
EncBiOut.bmiHeader.biYPelsPerMeter = 0;
EncBiOut.bmiHeader.biClrUsed = 0;
EncBiOut.bmiHeader.biClrImportant = 0;

if (big)
{
EncBiOut.bmiHeader.biWidth = 320;
EncBiOut.bmiHeader.biHeight = 240;
EncBiOut.bmiHeader.biSizeImage = 320*240*3;
}
else
{
EncBiOut.bmiHeader.biWidth = 160;
EncBiOut.bmiHeader.biHeight = 120;
EncBiOut.bmiHeader.biSizeImage = 160*120*3;
}

if (ICDecompressBegin(hic, &EncBiOut, &EncBiIn) != ICERR_OK)
{
ShowMessage("初始化解码器错误!");
return ;
}

frames = 0;
}

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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