可以的.例如象下面那样.当然,得修改一下Create的过程.
都不明白这些问题为何老是讨论来讨论去.
unit MyAsyncReaderUnit;
interface
uses Classes,DirectShow9,Windows,SysUtils;
type PLSample = ^TLSample;
TLSample = record
Sample:IMediaSample;
Value
Word;
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
Word):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
Byte;
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
Word):boolean;
var s
LSample;
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.