unit Unit_StreamKernel;
{--------------------------------------------------
神龙卡流式播放核心单元
作者:陈经韬.lovejingtao@21cn.com.
功能:流方式播放加密,非加密视频文件
创建日期:2003年11月6日
修改记录:
2003年11月7日,添加对Dat文件的支持
---------------------------------------------------}
var
iPack:integer;
ghMPEGStream:Byte= 0;//神龙卡句柄
gszFileName:LPTSTR;//播放文件名称
FVideoFormat : TVideoFormat;//播放文件类型:MPEG/DVD
FAudioChannel : TAudioChannel;//播放声道
FStreamPlayStatus
WORD;//播放状态
//bIsCyFile:Boolean;//是否为加密文件
FAudioVolume:integer=50;//音量
FAudioMute:Boolean=False;//是否为静音
binitializationFmpCard:Boolean=False;
bisPause:Boolean=False;
gbTvVgaOUTFlag:integer=FMPF_VGA;
hMainHwnd,hDisplayHwnd:HWND;
FVideoType:TVideoType;
....
function FMPCallbackProc( bMsg:BYTE;
hMPEGStream:BYTE;dwValue
WORD):WORD;stdcall;
var
Buf
Buf;
TempBuf:TVideoBuffer;
iRead
WORD;
i:integer;
iDatHeadPos:integer;
begin
Buf:= Pointer(FMPGet(hMPEGStream, FMPI_STM_USER));
case bMsg of
FMPM_BUF_CREATE://创建缓冲区
begin
Buf:=GlobalAllocPtr(GMEM_FIXED,Sizeof(TBuf));
//Buf:=GetMemory(Sizeof(TBuf));
if Buf=nil then
begin
MessageBox(0,'分配内存出错,可能是内存不足!','错误',MB_ICONEXCLAMATION);
Result:=FMPE_DOS;
Exit;
end;
FillChar(Buf^,Sizeof(TBuf),0);
Buf^.hFile:=CreateFile(gszFileName,//TFMP_OPEN_STRUCT(dwValue).lpFileName,
GENERIC_READ,
FILE_SHARE_READ,
Nil,
OPEN_EXISTING,
0,
0);
if (Buf^.hFile=INVALID_HANDLE_VALUE) then
begin
MessageBox(0,'打开文件出错!','错误',MB_ICONEXCLAMATION);
GlobalFreePtr(Buf);
//FreeMemory(buf);
Result:=FMPE_DOS;
Exit;
end;
//---------------------------------------------
case FVideoType of
vtDat:
begin
iDatHeadPos:=GetDatFileHead(gszFileName);
FileSeek(Buf^.hFile,iDatHeadPos,soFrombegin
ning);
end;
vtCyDATDVD:
begin
iPack:=0;
FileSeek(Buf^.hFile,3,soFrombegin
ning);
//MessageBox(0,Pchar(inttostr(iPack)),'',0);
MyStream.Clear;
for i:=1 to 100do
begin
ReadFile(Buf^.hFile,TempBuf,MAX_BUF_SIZE,iRead,nil);
UnCryptBuf(TempBuf,iRead);
//MessageBox(0,Pchar(inttostr(iRead)),'',0);
MyStream.Write(TempBuf,iRead);
// CopyMemory(Buf^.Buffer[Buf^.wIndex],@TempBuf,iRead);
end;
MyStream.Position:=0;
end;
end;
//---------------------------------------------
for i := 0 to MAX_BUF_NUMBER-1do
//GetMem(Buf^.Buffer
,MAX_BUF_SIZE + 2);
Buf^.Buffer:=GlobalAllocPtr(GMEM_FIXED,MAX_BUF_SIZE + 2);
//Buf^.Buffer:=GetMemory(MAX_BUF_SIZE + 2);
Buf^.wIndex := 0;
Buf^.dwSize := 0;
//存储缓冲区结构到用户段
FMPSet(hMPEGStream,FMPI_STM_USER, DWORD(Buf));
//在到缓冲区3/4时,触发填充下一个缓冲区
FMPSet(hMPEGStream, FMPI_BUF_POS, DWORD(Trunc(MAX_BUF_SIZE* 0.75)));
end;
FMPM_BUF_CLOSE ://关闭缓冲区
begin
CloseHandle(Buf^.hFile);
for i:=0 to MAX_BUF_NUMBER-1do
GlobalFreePtr(Buf^.Buffer);
GlobalFreePtr(Buf);
end;
FMPM_BUF_SEEK://跳跃
begin
SetFilePointer(Buf^.hFile,dwValue,nil,FILE_begin
);
end;
FMPM_BUF_POS://读数据
begin
if FVideoType=vtCyDATDVD then
begin
//MessageBox(0,Pchar(inttostr(iPack)),'',0);
if iPack<100 then
begin
iRead:=MyStream.Read(TempBuf,MAX_BUF_SIZE);
//MessageBox(0,Pchar(inttostr(iRead)),'',0);
// ReadFile(Buf^.hFile,TempBuf,MAX_BUF_SIZE,iRead,nil);
// if (TempBuf[iRead-3]=67) and (TempBuf[iRead-2]=74) and (TempBuf[iRead-1]=84) then
iRead:=iRead-3;
// UnCryptBuf(TempBuf,iRead);
CopyMemory(Buf^.Buffer[Buf^.wIndex],@TempBuf,iRead);
Buf^.dwSize:=iRead;
Inc(iPack);
//MessageBox(0,Pchar(inttostr(iPack)),'',0);
end
else
ReadFile(Buf^.hFile,Buf^.Buffer[Buf^.wIndex]^,MAX_BUF_SIZE,Buf^.dwSize,nil);
//强烈注意!!!!
end
else
if FVideoType=vtCyMpg then
begin
//TempBuf
ReadFile(Buf^.hFile,TempBuf,MAX_BUF_SIZE,iRead,nil);
if (TempBuf[iRead-3]=67) and (TempBuf[iRead-2]=74) and (TempBuf[iRead-1]=84) then
iRead:=iRead-3;
UnCryptBuf(TempBuf,iRead);
CopyMemory(Buf^.Buffer[Buf^.wIndex],@TempBuf,iRead);
Buf^.dwSize:=iRead;
end
else
ReadFile(Buf^.hFile,Buf^.Buffer[Buf^.wIndex]^,MAX_BUF_SIZE,Buf^.dwSize,nil);
//强烈注意!!!!
end;
FMPM_BUF_EMPTY : // 缓冲区空
begin
FMPSet(hMPEGStream, FMPI_BUF_SIZE,Buf^.dwSize );
FMPSet(hMPEGStream, FMPI_BUF_ADDRESS, DWORD(Buf^.Buffer[Buf^.wIndex]));
Inc(Buf^.wIndex);
if (Buf^.wIndex = MAX_BUF_NUMBER) then
Buf^.wIndex:=0;
end;
FMPM_COMPLETED ://操作完成
begin
if dwValue = 3 then
// 播完
begin
FStreamPlayStatus:=FMPF_STOPPED;
ShowWindow(hDisplayHwnd,SW_Hide);
//if ghMPEGStream <>0 then
FMPStop( ghMPEGStream );
//if AutoPlayNext then
// PostMessage(MainForm.Handle, FMP_NEXT, 0, 0)
//else
//Showmessage('已播完,按停唱播下一首');
end;
end ;
FMPM_ERROR://错误
begin
end;
end;
Result:=0;
end;