轉換基於DirectX的VC++網絡播放器代碼------->delphi+dspack!歡迎高手入內! (100分)

L

ljy_17

Unregistered / Unconfirmed
GUEST, unregistred user!
我剛接觸DirectX編程,而且用的是delphi+dspack!
偶得到一個基於DirectX的VC++網絡播放器代碼!實在沒有能力轉換為DELPHI!
所以請大家幫忙轉換!其實傳送部分可不必轉換!隻要轉換播放內存的部分就可!
我先貼出修改過的memfile文件!
有意轉換者請留下EMAIL,我將所有代碼發送到你們的信箱!

//
// MemFilter.h
//
#ifndef __MemFilter_h__
#define __MemFilter_h__

#include <streams.h>
#include <stdio.h>
#include "asyncio.h"
#include "asyncrdr.h"
#include "CMediaSocketClient.h"
#include "CDataAdmin.h"
#include "MyDef.h"


//////////////////////////////////////////////////////////////////////
// Define an internal filter that wraps the base CBaseReader stuff //
//////////////////////////////////////////////////////////////////////
class CMemStream : public CAsyncStream
{
private:
CCritSec m_csLock;
CDataAdmin * m_pDataList;
ULONG m_ulPositionInPack;
// Total length available
LONGLONG m_llLength;
// Bytes totally read
DWORD m_dwTimeStart;

public:
CMemStream(CDataAdmin* inBuffer)
{
m_pDataList = inBuffer;
m_ulPositionInPack = 0;
m_llLength = 0;

}

HRESULT SetPointer(LONGLONG llPos)
{
return S_OK;
}

HRESULT Read(PBYTE pbBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead)
{
if (m_pDataList == NULL)
return S_FALSE;

CAutoLock lck(&amp;m_csLock);
DWORD dwHaveRead = 0;
PMPEG1_PACK pPack = NULL;

while (dwHaveRead < dwBytesToRead)
{
if (dwBytesToRead - dwHaveRead >= MPEG1_PACK_SIZE - m_ulPositionInPack)
{
// Just copy the whole pack data
pPack = m_pDataList->GetDataBuffer();
if (pPack != NULL)
{
CopyMemory((PVOID)(pbBuffer + dwHaveRead),
(PVOID)((PBYTE)(pPack) + m_ulPositionInPack), (SIZE_T)MPEG1_PACK_SIZE - m_ulPositionInPack);
m_pDataList->ReleaseDataBuffer(pPack);
dwHaveRead += MPEG1_PACK_SIZE - m_ulPositionInPack;
m_ulPositionInPack = 0;
}
else
if (m_pDataList->IsFlushing())
{
// FILE * fp = fopen("c://log.txt","a+");
// fprintf(fp,"failed!/n");
// fclose(fp);

return E_FAIL;
}
else

{
// FILE * fp = fopen("c://log.txt","a+");
// fprintf(fp,"SLEEP!/n");
// fclose(fp);

Sleep(10);
}
}
else

{
// Copy part of the pack data
pPack = m_pDataList->PointToDataHead();
if (pPack != NULL)
{
m_ulPositionInPack = dwBytesToRead - dwHaveRead;
CopyMemory((PVOID)(pbBuffer + dwHaveRead),
(PVOID)(pPack), (SIZE_T)m_ulPositionInPack);
dwHaveRead += m_ulPositionInPack;
}
else
if (m_pDataList->IsFlushing())
{
// FILE * fp = fopen("c://log.txt","a+");
// fprintf(fp,"failed!/n");
// fclose(fp);

return E_FAIL;
}
else

{
// FILE * fp = fopen("c://log.txt","a+");
// fprintf(fp,"SLEEP!/n");
// fclose(fp);
Sleep(10);
}
}
}
*pdwBytesRead = dwBytesToRead;

return S_OK;
}

LONGLONG Size(LONGLONG *pSizeAvailable)
{
*pSizeAvailable = m_llLength;
return 0x7fffffffff;
}

DWORD Alignment()
{
return 1;
}

void Lock()
{
m_csLock.Lock();
}

void Unlock()
{
m_csLock.Unlock();
}

void AddAvailableLength(LONGLONG inLength)
{
m_llLength += inLength;
}
};

class CMemReader : public CAsyncReader
{
public:

// We're not going to be CoCreate'd so wedo
n't need registration
// stuff etc
STDMETHODIMP Register()
{
return S_OK;
}
STDMETHODIMP Unregister()
{
return S_OK;
}
CMemReader(CMemStream *pStream, CMediaType *pmt, HRESULT *phr) :
CAsyncReader(NAME("Mem Reader"), NULL, pStream, phr)
{
m_mt = *pmt;
}
};

#endif // __MemFilter_h__
 
代码不难吗,就是头文件难的找...
 
没什么头文件啊,那些""的都是本程序的头文件,不是系统的头文件,整个代码不难啊

发到此处hzg115@sina.com
 
TO:诸葛白痴說得沒錯!會者不難!但想要轉換必須有DirectX的編程經驗才行!
代碼已發送到你的信箱,請查收!
 
给俺来一份,正好有个项目要做,用dspack近一年了
 
TO:coolsoft
請留下你的EMAIL!

 
我提…

沒人感興趣嗎?
 
发到我的email看看[:)]
lee@165e.com
 
看看下面的描述:
type
CAsyncReader=procedure (NAME('Mem Reader');nil;pStream;phr);
TCAsyncReader=CAsyncReader;

CMemStream = class(CAsyncStream)
private
m_csLock:CCritSec;
m_pDataList:CDataAdmin;
m_ulPositionInPack:ULONG;
m_llLength:LONGLONG;
m_dwTimeStart:DWORD;
public
constructor CMemStream(inBuffer:CDataAdmin);
function SetPointer(llPos:LONGLONG):HRESULT;
function Read(pbBuffer:pBYTE;dwBytesToRead:DWORD;bAlign:BOOL;pdwBytesRead:LPDWORD):HRESULT;
function Size(pSizeAvailable:LONGLONG):LONGLONG;
function Alignment:DWORD;
procedure Lock;
procedure Unlock;
end;

TCMemStream=CMemStream;

CMemReader = class(CAsyncReader)
public
constructor CMemReader(pStream:CMemStream;pmt:CMediaType;phr:HRESULT):CAsyncReader;
function _Register:HRESULT;
function _Unregister:HRESULT;
end;

TCMemReader=CMemReader;
 
TO:小雨哥
可以留下你的EMAIL嗎?我把整個程序發送到你的信箱!
 
老兄,俺就对DX没经验。。。:(

不过先发一份看看,:D:D
copy_paste@163.com
 
lovejingtao@21cn.com

一些以前收集的相关资料.
先说说memfile例子的整体框架。实际上,directshow已经封装好了几个类,CasyncReader和CasyncStream是我们最关心的,CasyncReader已经是个source filter了,而我们只需通过CasyncStream类就可以控制数据了。CasyncStream类很简单,都是一些纯虚函数。我们是继承它,把它的函数完善就行了。



现在把工作的重点放在CasyncStream类。Memfile是继承了它得到自己的类CmemStream。因为这个类有了一些函数的总体框架,所以我就用它做为父类了(当然,完全可以直接从CasyncStream继承)。有三个重要的函数:SetPointer(LONGLONG llPos),Read(PBYTE pbBuffer,DWORD dwBytesToRead,BOOL bAlign,LPDWORD pdwBytesRead)和Size(LONGLONG *pSizeAvailable)。其中重中之重是Read函数,(实际上我已经弃用SetPointer函数了)。所以的数据操作都是在这里完成的。下面通过具体的代码来说明。



参数的说明:
m_pbData 读写的内存数据指针
m_llLength 数据的总长度
m_llPosition 实际读写的内存数据位置指针
m_dwKBPerSec 播放的的速率
由于初期时,操作内存数据指针m_pbData总是出错,所以改用自己的指针。本来是打算用m_llPosition来虚拟个无限大的内存空间(实际就是循环0---max,读前面的数据,刷新后面的,接着读后面的,刷新前面的来达到这效果),可是要烦琐一些,有些临界条件难以判断。所以实际上是我只用了它的参数m_llLength。大家可以通过memfile的源代码来学习m_llPosition+ m_pbData的用途。
m_llLength是个非常重要的参数。如果你要做网络的实时监控,当然不希望播放了几个小时就停了。通过修改它可以达到你们需要的长度。它是LONGLONG型的,就是说2的64次方。足够播放n年了 : ) 。
NOTE:如果你把它改的小,不论你怎么添加内存数据都不能持续的播放。directshow播放完这个长度的数据后就自动的停止了。
首先,初始化参数:
m_PlayBuf = new BYTE[32768*10];//我自己定义的数据缓冲
m_Buf Size = 0;//缓冲区未播放的数据大小,开始没数据,当然为0
m_llLength = 4000000000000;//这个大小足够播放了,4T的数据
hMutex = CreateMutex(NULL,TRUE,"protect buf");//这是个HANDLE型的,用于播放和添加数据时,保护数据的完整性



接着就是Read函数了,它是自动调用的,而且是个work thread,参数pbBuffer是输出变量,就是要播放的数据,pdwBytesRead也是输出变量,表示读了的数据长度,其余是输入变量:
HRESULT Read(PBYTE pbBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead)
{
CAutoLock lck(&amp;m_csLock);
DWORD dwReadLength;



dwReadLength = dwBytesToRead;//只有在最后的数据包改写该参数(因为不一定会符合32768的大小,我默认不修改)
///////////////////////////handle buf
while (32768>m_Buf Size);//wait for add new data



WaitForSingleObject(hMutex, 1L);
file://这/一小段是关键
CopyMemory((PVOID)pbBuffer, (PVOID)m_PlayBuf,dwReadLength);//从我们的缓冲中得到要播放的数据
ReleaseMutex(hMutex);
m_Buf Size -= dwReadLength;//未播放的数据大小减去刚刚播放的数据量dwReadLength
CopyMemory((PVOID)m_PlayBuf, (PVOID)(m_PlayBuf+dwReadLength),m_Buf Size);//把未播放的数据移动到m_PlayBuf的开头,这样我们就不需要位置指针m_llPosition。这样有个好处,
 
sz_delphi@163.com 发给我看看。
 
TO: copy_paste,jingtao郵件已發送!請查收!!!
 
能给我发一份吗?xiaorou00@sina.com
 
我的email:coolsoft@963.net
 
w_gkai@163.com,试试。
 
奶奶的!道行太浅看不懂!
 
TO:ljy_17
我没时间做这个工作,贴出的代码是基于内存流的操作,没有涉及 DirectX ,
请不要在标题上写我的名字,请其他高手回答吧。注意看 jingtao 大侠的有关这
方面的帖子。
 
TO:小雨哥
謝謝你的回復!馬上更改標題!
如有給你帶來不便,請諒解…
 
顶部