关于怎么播放内存流中的数据的讨论。 (50分)

  • 主题发起人 主题发起人 lovinger_2000
  • 开始时间 开始时间
L

lovinger_2000

Unregistered / Unconfirmed
GUEST, unregistred user!
问题一
我将一媒体文件先读入PlayerSource: TMemoryStream;
因为需要对PlayerSource进行解密操作,解密后才能用TMediaplayer空间播放。请问TMediaPlayer空间怎么播放PlayerSource中的数据?
问题二
使用Dspack2.3控件,怎么播放PlayerSource呢?
——————————————————————————————
注:请不要使用先把PlayerStream转换为临时文件,在进行文件播放的办法,因为这样速度太受影响了。
 
DX SDK里面有 Memory Filter 的例子。
应该能够帮助你
 
To garden_p:
请问你说的是DirectX的SDK开发包里面有例子吗?谢谢回复,另外,没有现存的解决方法吗?
 
楼主,我从Dspack网上查到这样一个回答:
i guess there will never be a FilterGraph.RenderStream function because a MemoryStream can contain anything and the SourceFilter is not able to set the MediaType on the Output Pin. You need to create a SourceFilter. The AsyncReader Sample in this forum cando
this. If the MemoryStream changes dynamically, then
you will need to add a Callback to your Application to retrieve Samples.
他的问题是想用MemoryStream来播放,这个问题在Dspack上有好多,但都没有人回答,所以看来是无法解决了。[:)]
 
可以的.例如象下面那样.当然,得修改一下Create的过程.
都不明白这些问题为何老是讨论来讨论去.
unit MyAsyncReaderUnit;

interface

uses Classes,DirectShow9,Windows,SysUtils;

type PLSample = ^TLSample;
TLSample = record
Sample:IMediaSample;
Value:DWord;
end;


type
TMyAsyncReader = class(TThread)
private
FAvail:boolean;
queLocked:boolean;
PLst:TList;
DLst:TList;
Strm:TMemoryStream;
StrmLen:Int64;
procedure ProcessSample(ppSample:IMediaSample);
protected
procedure Execute;
override;
public
constructor Create(CreateSuspended: Boolean;
FileName:String);
destructor Destroy;
override;
property DataAvailable:boolean read FAvail;
function Request(ppSample:IMediaSample;
Value:DWord):boolean;
function GetFinished(out ppSample:IMediaSample;out pdwUser: DWORD):boolean;
function ReadFromStream(llPosition: int64;
lLength: Longint;
pBuffer: Pbyte):Int64;
property StreamLength:Int64 read StrmLen;
procedure FlushAll;
end;


implementation

{ TMyAsyncReader }

function min(a,b:int64):int64;
begin

if a<b then
result:=a else
result:=b;
end;


constructor TMyAsyncReader.Create(CreateSuspended: Boolean;
FileName:String);
begin

inherited Create(CreateSuspended);
if FileExists(FileName) then

begin

strm:=TMemoryStream.Create;
strm.LoadFromFile(FileName);
StrmLen:=strm.Seek(0,soEnd);
strm.Seek(0,sobegin
ning);
queLocked:=false;
end;

PLst:=TList.Create;
PLst.Capacity:=100;
DLst:=TList.Create;
DLst.Capacity:=100;

end;


destructor TMyAsyncReader.Destroy;
begin

if assigned(strm) then

strm.Free;
DLst.Free;
PLst.Free;
inherited Destroy;
end;


function TMyAsyncReader.ReadFromStream(llPosition: int64;
lLength: Longint;
pBuffer: Pbyte):Int64;
begin

if (llPosition+lLength) > strm.Size then

result := lLength - ((llPosition+lLength) - strm.Size)
else
result := lLength;
CopyMemory(pBuffer,Pointer(Integer(strm.Memory)+llPosition),result);
end;


procedure TMyAsyncReader.ProcessSample(ppSample:IMediaSample);
var ptr:PByte;
bb,be:REFERENCE_TIME;
readBytes:Int64;
begin

if ppSample.GetPointer(ptr)<>S_OK then

exit;
if ppSample.GetTime(bb,be)<>S_OK then

exit;
bb:=bb div 10000000;
be:=be div 10000000;
readBytes:=ReadFromStream(bb,be-bb,ptr);
ppSample.SetActualDataLength(readBytes);
end;


procedure TMyAsyncReader.Execute;
begin

while not Terminateddo

begin

if (PLst.Count>0) then
//and (not queLocked) then

begin

queLocked:=true;
ProcessSample(PLSample(PLst.Items[0]).Sample);
DLst.Add(PLst.Items[0]);
PLst.Delete(0);
FAvail := DLst.Count>0;
queLocked:=false;
end;

end;

end;


procedure TMyAsyncReader.FlushAll;
begin

while queLockeddo
;
queLocked:=true;
PLst.Clear;
DLst.Clear;
FAvail:=false;
queLocked:=false;
end;


function TMyAsyncReader.Request(ppSample:IMediaSample;
Value:DWord):boolean;
var s:PLSample;
begin

while queLockeddo
;
queLocked:=true;
New(s);
s.Sample:=ppSample;
s.Value:=Value;
PLst.Add(s);
queLocked:=false;
result:=true;
end;


function TMyAsyncReader.GetFinished(out ppSample:IMediaSample;out pdwUser: DWORD):boolean;
begin

result:=false;
while queLockeddo
;
if DLst.Count=0 then
exit;
queLocked:=true;
ppSample:=PLSample(DLst.Items[0]).Sample;
pdwUser:=PLSample(DLst.Items[0]).Value;
Dispose(DLst.Items[0]);
DLst.Delete(0);
FAvail := DLst.Count>0;
queLocked:=false;
result:=true;
end;


end.

 
To jingtao:
请问你说的方法是添加一自定义单元MyAsyncReaderUnit,然后使用DSPack中的MediaSample组件吗?能不能把以上的代码加一些注释,以及说明一下工作流程或者原理,谢谢你。如果需要分,我可以加,不过我觉得分没有什么意思……
 
关键在于自己建立一个过滤器
上面是一个过滤器的CODE
工作原理你自己看DIRECTX文档吧.不是几句话说的清楚的/两年没弄DIRECTX了.大学的时候弄过一下.
 
请问哪里可以下载DX的SDK开发包呢?
 
多人接受答案了。
 
后退
顶部