J
jingtao
Unregistered / Unconfirmed
GUEST, unregistred user!
不记得谁弄的了....unit xlOSD;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, UnitRmOSD, ActiveX, UnitOSDFunctions, Dialogs, ExtCtrls,Jpeg;const HEADERLONG = 1032;
//osd文件头部大小 c_PANELVALUE = $4F;
type TOsdSWMode = (ssSWText,ssSWImage,ssSWTextImage,ssSWNone);
TScrollStyle = (ssLeftToRight, ssRightToLeft, ssTopToBottom, ssBottomToTop,ssNoScroll);
{ TxlOSD } TxlOSD = class (TComponent) private FFree: Boolean;
//是否空闲 FPOldData: Pointer;
//OSD文件指针 FPBakData: Pointer;
//当文字和图片同时显示时,保存的数据。 FPPalette: Pointer;
//调色板指针 FPData: Pointer;
//数据指针 FPTempData: Pointer;
//文字数据指针 FPBitmapData: Pointer;
//位图数据指针 可用于模拟动画 FBitmapFrames: Integer;
//位图帧数 FPlaying: Boolean;
FTimer: TTimer;
FInterval: Cardinal;
pOSD: IRmStream;
pDevice: IRmControlNode;
pMemAlloc: IRmMapMem;
rc_dest: MPEG_OVERLAY_RECT;
FSize: RMuint32;
//OSD文件大小 FCaptionScrolled: Boolean;
FCaptionX: Integer;
FCaptionY: Integer;
FOldCaptionX: Integer;
FOldCaptionY: Integer;
FOldCaptionWidth: Integer;
FOldCaptionHeight: Integer;
FCaptionWidth: Integer;
FCaptionHeight: Integer;
FScrollStyle: TScrollStyle;
FScrollStep: Integer;
FScrolled: Boolean;
FIsUsePanel: Boolean;
FRectx: Integer;
FRecty: Integer;
FRectWidth: Integer;
FRectHeight: Integer;
FBitmapY: Integer;
FBitmapX: Integer;
FCaption: TStringList;
FBitmapFile: string;
FBitmap: TBitmap;
FBitmapWidth: Integer;
FBitmapHeight: Integer;
FActive: Boolean;
FVisible: Boolean;
FHeight: Integer;
FWidth: Integer;
FFont: TFont;
FY: LongWord;
FX: LongWord;
FIsShowBitmap: Boolean;
FIsFillGrid: Boolean;
FlogFont: TlogFont;
FSwMode: TOsdSWMode;
FStretch: Boolean;
FInitOSD : Boolean;
function MakeBitmap(var AmStream: TMemoryStream): Boolean;
procedure ShowOSD;
function WriteToOSD(var AmStream: TMemoryStream): Boolean;
procedure WriteData(pdata: Pointer;
Size: RMuint32);
function InitDevice: Boolean;
procedure ClearOldData(x, y, AWidth, AHeight: Integer);
procedure SetCaptionPos;
procedure CalPos(var ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer);
function CopyFromTempData(ASrcx, ASrcy: Integer;
ASize: Integer;
ALines: Integer;
ADstx, ADsty: Integer): Boolean;
function CopyDataToOldData(APSrcData, APDstData: Pointer;
ASrcx, ASrcy: Integer;
ASize: Integer;
ALines: Integer;
ADstx, ADsty: Integer): Boolean;
procedure MakePanel;
procedure EditWordValue;
procedure OSDTimer(Sender: TObject);
function ConvertOSDFromWord(var AOutStream: TMemoryStream): Boolean;
function GetOSDDataFromStream(var ASourceStream, AOutStream: TmemoryStream): Boolean;
function CopyPaletteToOldData(AmsSrc: TMemoryStream): Boolean;
function CopyBitmapDataToOldData: Boolean;
procedure SetActive(const Value: Boolean);
procedure SetBitmap(const Value: TBitmap);
procedure SetBitmapFile(const Value: string);
procedure SetBitmapX(const Value: Integer);
procedure SetBitmapY(const Value: Integer);
procedure SetCaption(Value: TStringList);
procedure SetCaptionScrolled(const Value: Boolean);
procedure SetCaptionX(const Value: Integer);
procedure SetcaptionY(const Value: Integer);
procedure SetInterval(const Value: Cardinal);
procedure SetScrollStyle(const Value: TScrollStyle);
procedure SetHeight(const Value: Integer);
procedure SetWidth(const Value: Integer);
procedure SetFont(const Value: TFont);
procedure SetX(const Value: LongWord);
procedure SetY(const Value: LongWord);
procedure SetScrollStep(const Value: Integer);
procedure SetScrolled(const Value: Boolean);
procedure SetVisible(const Value: Boolean);
procedure SetCaptionRect(const Value: TRect);
procedure SetIsUsePanel(const Value: Boolean);
procedure SetRectHeight(const Value: Integer);
procedure SetRectWidth(const Value: Integer);
procedure SetRectx(const Value: Integer);
procedure SetRecty(const Value: Integer);
procedure SetIsShowBitmap(const Value: Boolean);
procedure SetIsFillGrid(const Value: Boolean);
public constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
procedure InitTempData;
function Play: Boolean;
function Stop: Boolean;
property Active: Boolean read FActive write SetActive;
property Caption: TStringList read FCaption write SetCaption;
property BitmapFile: string read FBitmapFile write SetBitmapFile;
property Bitmap: TBitmap read FBitmap write SetBitmap;
property ScrollStyle: TScrollStyle read FScrollStyle write SetScrollStyle default ssRightToLeft;
property BitmapX: Integer read FBitmapX write SetBitmapX default 1;
property BitmapY: Integer read FBitmapY write SetBitmapY default 1;
property CaptionX: Integer read FCaptionX write SetCaptionX default 1;
property CaptionY: Integer read FCaptionY write SetCaptionY default 300;
property CaptionScrolled: Boolean read FCaptionScrolled write SetCaptionScrolled;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property Width: Integer read FWidth write SetWidth default 640;
property Height: Integer read FHeight write SetHeight default 480;
property Font: TFont read FFont write SetFont;
property X: LongWord read FX write SetX default 0;
property Y: LongWord read FY write SetY default 0;
property Scrolled: Boolean read FScrolled write SetScrolled default False;
property ScrollStep: Integer read FScrollStep write SetScrollStep default 10;
property Visible: Boolean read FVisible write SetVisible default False;// property IsUsePanel: Boolean read FIsUsePanel write SetIsUsePanel;
property Rectx: Integer read FRectx write SetRectx;
property Recty: Integer read FRecty write SetRecty;
property RectWidth: Integer read FRectWidth write SetRectWidth;
property RectHeight: Integer read FRectHeight write SetRectHeight;// property IsShowBitmap: Boolean read FIsShowBitmap write SetIsShowBitmap;
property IsFillGrid: Boolean read FIsFillGrid write SetIsFillGrid;
property SwMode : TOsdSWMode read FSwMode write FSwMode;
property Stretch : Boolean read FStretch write FStretch;
property isInitOK : Boolean read FInitOSD;
end;
implementation{************************************ TxlOSD ************************************}constructor TxlOSD.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWidth := 650;
FHeight := 525;
FRectx := 0;
FRecty := 0;
FRectWidth := FWidth;
FRectHeight := FHeight;
FBitmapX := 10;
FBitmapY := 20;
FCaptionX := 20;
FCaptionY := 20;
FOldCaptionX := 0;
FOldCaptionY := 200;
FX := 30;
FY := 10;
FScrollStep := 10;
FIsUsePanel := False;
FScrolled := False;
FScrollStyle:= ssTopToBottom;
FSwMode:=ssSWTextImage;
FStretch:=False;
FCaption := TStringList.Create;
FBitmap := TBitmap.Create;
FTimer := TTimer.Create(self);
FTimer.Enabled := False;
FTimer.Interval := 10;
FTimer.OnTimer := OSDTimer;//MovePanel;
FFont := TFont.Create;
FFont.Color := clBlue;
FFont.Size := 20;
FFont.Name := '幼圆';
FIsFillGrid := True;
FPlaying := False;
FVisible := False;
FFree := True;
FInitOSD:=InitDevice();
if FInitOSD=False then
begin
// MessageBox(0,'初试化OSD接口失败!!!','OSD叠加程序',MB_ICONEXCLAMATION);
end;
Play();
end;
//------------------------------------------------------------------------------destructor TxlOSD.Destroy;
begin
Stop();
if FTimer <> nil then
begin
FTimer.Enabled := False;
FTimer.Free;
end;
if FPOldData <> nil then
FreeMem(FPOldData);
if FPBakData <> nil then
FreeMem(FPBakData);
if FPTempData <> nil then
FreeMem(FPTempData);
if FFont <> nil then
FFont.Free;
if FBitmap <> nil then
FBitmap.Free;
if FCaption <> nil then
FCaption.Free;
CoUninitialize();
inherited Destroy;
end;
//------------------------------------------------------------------------------function TxlOSD.MakeBitmap(var AmStream: TMemoryStream): Boolean;var OSDBitmap: TBitmap;
Rect : TRect;
TmpBitmap: TBitmap;
MyJpeg: TJpegImage;
ExtStr : String;
begin
Result := False;
if AmStream.Size > 0 then
AmStream.Clear;
OSDBitmap := TBitmap.Create;
TmpBitmap := TBitmap.Create;
try OSDBitmap.Width := FWidth;
OSDBitmap.Height := FHeight;
OSDBitmap.PixelFormat := pf8bit;
Rect.Top:=0;
Rect.Left:=0;
Rect.Bottom:=OSDBitMap.Height ;
Rect.Right:=OSDBitMap.Width;
OSDBitmap.Canvas.Brush.Color :=clLime;
OSDBitMap.Canvas.FillRect(Rect);
if FIsShowBitmap and Fileexists(BitmapFile) then
begin
ExtStr:=Lowercase(ExtractFileExt(BitmapFile));
if not((ExtStr='.jpg')or(ExtStr='.jpeg')) then
TmpBitmap.LoadFromFile(FBitmapFile) else
begin
MyJpeg:= TJpegImage.Create;
try myjpeg.LoadFromFile(BitmapFile);
TmpBitmap.Assign(myjpeg);
finally myjpeg.Free;
end;
end;
TmpBitmap.Transparent:=True;
if FStretch=False then
OSDBitMap.Canvas.Draw(FBitmapX,FBitmapY,TmpBitmap) else
OSDBitMap.Canvas.StretchDraw(Rect,TmpBitmap);
end;
OSDBitmap.SaveToStream(AmStream);
Result := True;
finally TmpBitmap.Free;
OSDBitmap.Free;
end;
end;
//------------------------------------------------------------------------------//******************初始化********************************function TxlOSD.InitDevice: Boolean;var hr: HRESULT;
pIRmObjectFinder: IRmObjectFinder;
dwTvOutKeep: RMint32;
HwLibVersion, dwTvOut: RMint32;
begin
Result := False;
CoInitialize(nil);
hr := CoCreateInstance( CLSID_RMBASE, nil, CLSCTX_INPROC_SERVER, IID_IRmObjectFinder, pIRmObjectFinder );
if FAILED(hr) then
Exit; hr := pIRmObjectFinder.FindObject(nil, FIRST_AVALIABLE_INSTANCE, CATEGORY_PIN_OSD, IID_IRmStream, pOSD); pIRmObjectFinder := nil;
if FAILED(hr) then
Exit;
pOSD.Reset();
pDevice := nil;
hr := pOSD.QueryInterface(IID_IRmControlNode, pDevice);
if FAILED(hr) then
Exit;
hr := pOSD.QueryInterface(IID_IRmMapMem, pMemAlloc);
if FAILED(hr) then
Exit;
pDevice.GetAttributes(MpegAttrCodeVersion, HwLibVersion);
pDevice.GetAttributes(MpegAttrVideoTv, dwTvOutKeep);
dwTvOut := dwTvOutKeep and (not OUTPUT_OFF);
if HwLibVersion < 9 then
dwTvOut := dwTvOut or SET_TV else
begin
dwTvOut := dwTvOut or SET_TV or $80000000;
dwTvOut := dwTvOut and (not SET_HDTV);
end;
pDevice.SetAttributes(MpegAttrVideoTv, dwTvOut);
Result := True;
end;
//------------------------------------------------------------------------------//*****************清除上一次的滚动文字数据***************procedure TxlOSD.ClearOldData(x, y, AWidth, AHeight: Integer);var p: Pointer;
i: Integer;
begin
CopyMemory(FPData,FPBakData,FSize-HEADERLONG);
p := Ptr(DWORD(FPData) + FWidth * y + x);
for i := 0 to AHeight - 1do
begin
p := Ptr(DWORD(p) + FWidth);
FillChar(P^, AWidth , $7F);
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.OSDTimer(Sender: TObject);var pLine, ptmp: Pointer;
i, ii: Integer;
iX: Integer;
iY: Integer;
p: Pointer;
srcx,srcy,isize,lines,dstx,dsty: Integer;
begin
if (FCaption.Count < 0) or (not FScrolled) or (not FActive) then
begin
FTimer.Enabled := False;
Exit;
end;
if not FFree then
Exit;
if (FSwMode=ssSWImage) then
Exit;
FFree := False;
//if not FIsUsePanel then
ClearOldData(FOldCaptionx, FOldCaptionY, FOldCaptionWidth, FOldCaptionHeight);
//清除上一次内容 SetCaptionPos;
//改变坐标 CalPos(srcx,srcy,isize,lines,dstx,dsty);
//计算出现范围 if FIsUsePanel then
MakePanel();
//加面板条 CopyFromTempData(srcx,srcy,isize,lines,dstx,dsty);
//复制数据 if FIsUsePanel then
EditWordValue();
// WriteData(FPOldData, FSize);
//写OSD数据end;
//------------------------------------------------------------------------------function TxlOSD.Play: Boolean;var ms: TMemoryStream;
begin
Result := False;
if FPlaying then
Exit;
if pOSD <> nil then
begin
Result := FAILED(pOSD.Play);
ms := TMemoryStream.Create;
try FPlaying := True;
FActive := True;
finally ms.Free;
end;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetActive(const Value: Boolean);
begin
if FActive <> Value then
begin
FActive := Value;
if Value then
Play else
Stop;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmap(const Value: TBitmap);
begin
if Value <> nil then
begin
FBitmap.Assign(Value);
FBitmapFile := '';
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmapFile(const Value: string);
begin
if Value <> FBitmapFile then
FBitmapFile := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmapX(const Value: Integer);
begin
if FBitmapX <> Value then
FBitmapX := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmapY(const Value: Integer);
begin
if FBitmapY <> Value then
FBitmapY := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaption(Value: TStringList);
begin
if nil <> Value then
FCaption.Assign(Value);
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaptionScrolled(const Value: Boolean);
begin
if FCaptionScrolled <> Value then
FCaptionScrolled := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaptionX(const Value: Integer);
begin
if FCaptionX <> Value then
begin
FCaptionX := Value;
FOldCaptionX := Value;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetcaptionY(const Value: Integer);
begin
if FCaptionY <> Value then
begin
FCaptionY := Value;
FOldCaptionY := Value;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetFont(const Value: TFont);
begin
if FFont <> nil then
begin
if Value is TFont then
FFont.Assign(Value);
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetHeight(const Value: Integer);
begin
if FHeight <> Value then
FHeight := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetInterval(const Value: Cardinal);
begin
if FInterval <> Value then
begin
FInterval := Value;
FTimer.Interval := Value;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetScrolled(const Value: Boolean);
begin
if FScrolled <> Value then
FScrolled := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetScrollStep(const Value: Integer);
begin
if FScrollStep <> Value then
FScrollStep := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetScrollStyle(const Value: TScrollStyle);
begin
if FScrollStyle <> Value then
FScrollStyle := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetWidth(const Value: Integer);
begin
if FWidth <> Value then
FWidth := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetX(const Value: LongWord);
begin
if FX <> Value then
FX := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetY(const Value: LongWord);
begin
if FY <> Value then
FY := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.ShowOSD;var msSrc, msDest: TMemoryStream;
mslines: TMemoryStream;
begin
msSrc := TMemoryStream.Create;
msDest := TMemoryStream.Create;
mslines := TMemoryStream.Create;
try case FSwMode of ssSWImage : FIsShowBitmap:=True;
ssSWText : FIsShowBitmap:=False;
ssSWTextImage : FIsShowBitmap:=True;
end;
MakeBitmap(msSrc);
Streamrgb2x(msSrc, msDest);
if (FSwMode<>ssSWImage) and (FCaption.Count > 0) then
begin
InitTempData();
end else
FScrolled := False;
WriteToOSD(msDest);
if (FSwMode<>ssSWImage) and (FPTempData <> nil) and (not Scrolled) then
CopyFromTempData(0, 0, FOldCaptionWidth, FOldCaptionHeight, FOldCaptionX, FOldCaptionY);
WriteData(FPOldData, FSize);
finally msSrc.Free;
msDest.Free;
mslines.Free;
end;
FVisible := True;
FTimer.Enabled := FScrolled;
end;
//------------------------------------------------------------------------------function TxlOSD.Stop: Boolean;
begin
Result := False;
if not FPlaying then
Exit;
FTimer.Enabled := False;
while not FFreedo
begin
end;
FFree := False;
if pOSD <> nil then
begin
Result := FAILED(pOSD.Stop);
if pDevice <> nil then
//pDevice.SetAttributes(MpegAttrVideoTv,dwTvOutKeep) pDevice.SetAttributes(MpegAttrOsdOFF,1);
FActive := False;
FPlaying := False;
FVisible := False;
end;
end;
//------------------------------------------------------------------------------//*****************写入OSD数据到pDevice中*************************procedure TxlOSD.WriteData(pdata: Pointer;
Size: RMuint32);var hdr: HEADER;
ovr: RMOVERLAPIO;
begin
FillChar(hdr, Sizeof(hdr), 0);
hdr.multi.Count := 1;
hdr.multi.Size := SizeOf(HEADER);
hdr.header.Size := SizeOf(RMSTREAM_HEADER);
hdr.header.pData := pdata;
hdr.header.FrameExtent := Size;
ovr.do_not_use[0] := 0;
ovr.do_not_use[1] := 0;
ovr.do_not_use[2] := 0;
ovr.do_not_use[3] := 0;
ovr.hEvent := CreateEvent(nil, True, False, nil);
pOSD.Write(@hdr.multi, ovr);
WaitForSingleObject(ovr.hEvent,10000);
pDevice.SetAttributes(MpegAttrOsdDest, LongInt(@rc_dest));
pDevice.SetAttributes(MpegAttrOsdON, 1);
CloseHandle(ovr.hEvent);
FFree := True;
end;
//------------------------------------------------------------------------------//************转换成OSD数据**************************function TxlOSD.WriteToOSD(var AmStream: TMemoryStream): Boolean;var phys: Pointer;
hdr: HEADER;
Buff_8: array[0..7] of Byte;
pshared: Pointer;
i,j: Integer;
b: Boolean;
p,ptmp: PBYTE;
begin
Result := False;
AmStream.Seek(0, soFrombegin
ning);
AmStream.ReadBuffer(Buff_8[0], SizeOf(Buff_8)); // 从前8个字节中算出图形大小Width, Height FSize := (buff_8[1] shl (8*2)) or (buff_8[2] shl 8) or buff_8[3];
rc_dest.X := FX;
rc_dest.Y := FY;
rc_dest.cX := (buff_8[4] shl 8) or buff_8[5];
rc_dest.cY := (buff_8[6] shl 8) or buff_8[7]; // 重新读取所有的数据 if FSize = 0 then
Exit;
AmStream.Seek(0, soFrombegin
ning);
if FPoldData <> nil then
begin
FreeMem(FPOldData);
FPOldData := nil;
end;
if FPBakData <> nil then
begin
FreeMem(FPBakData);
FPBakData := nil;
end;
Getmem(pshared, FSize);
Getmem(FPOldData, FSize);
if pshared = nil then
Exit;
AmStream.ReadBuffer(pshared^, FSize);
if FIsFillGrid then
begin
for i := 0 to FHeight - 1do
begin
p := PBYTE(DWORD(pshared) + 1032 + i * FWidth);
ptmp := p;
if Odd(i) then
for j := 0 to FWidth - 1do
begin
if Odd(j) then
ptmp^ := $7F;
ptmp := PBYTE(DWORD(p) + j);
end else
for j := 0 to FWidth - 1do
begin
if not Odd(j) then
ptmp^ := $7F;
ptmp := PBYTE(DWORD(p) + j);
end;
end;
end;
WriteData(pshared, FSize);
CopyMemory(FPOldData, pshared, FSize);
FPPalette := Pointer(DWORD(FPOldData) + 8);
FPData := Pointer(DWORD(FPOldData) + HEADERLONG);
FreeMem(pshared);
Getmem(FPBakData, FSize-HEADERLONG);
CopyMemory(FPBakData,FPData, FSize-HEADERLONG);
Result := True;
end;
//------------------------------------------------------------------------------//***************复制数据到OSD数据中****************************function TxlOSD.CopyFromTempData(ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer): Boolean;var pSrc, pDst: Pointer;
i, j, ii: Integer;
b: Boolean;
ptmp: PBYTE;
begin
Result := False;
pSrc := Pointer(DWORD(FPTempData) + ASrcy * FCaptionWidth + ASrcx);
pDst := Pointer(DWORD(FPOldData) + HEADERLONG + ADsty * FWidth + ADstx);
for i := 0 to ALines - 1do
begin
CopyMemory(pDst, pSrc, ASize);
pSrc := Ptr(DWORD(pSrc) + FCaptionWidth);
pDst := Ptr(DWORD(pDst) + FWidth);
end;
Result := True;
end;
//------------------------------------------------------------------------------//*************改变滚动文字的坐标*************************procedure TxlOSD.SetCaptionPos;
begin
case FScrollStyle of ssLeftToRight: begin
if FCaptionX >= FRectx + FRectWidth then
FCaptionX := FRectx - FCaptionWidth + 10 else
Inc(FCaptionX, FScrollStep);
end;
ssRightToLeft: begin
if FCaptionX <= FRectx - FCaptionWidth then
FCaptionX := FRectx + FRectWidth - 10 else
Dec(FCaptionX, FScrollStep);
end;
ssTopToBottom: begin
if FCaptionY >= FRecty + FRectHeight then
FCaptionY := FRecty - FCaptionHeight + 10 else
Inc(FCaptionY, FScrollStep);
end;
ssBottomToTop: begin
if FCaptionY <= FRecty - FCaptionHeight then
FCaptionY := FRecty + FRectHeight - 10 else
Dec(FCaptionY, FScrollStep);
end;
end;
end;
//------------------------------------------------------------------------------//************计算要复制的数据cx,cy, 坐标**************************procedure TxlOSD.CalPos(var ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer);
begin
if (FCaptionX >= FRectx) and (FCaptionX < FRectx + FRectWidth) then
//FCaptionX 在画中 begin
ADstx := FCaptionX;
ASrcx := 0;
if FCaptionX + FCaptionWidth >= FRectx + FRectWidth then
ASize := FRectx + FRectWidth - FCaptionX else
ASize := FCaptionWidth;
end else
begin
if (FCaptionX >= FRectx + FRectWidth) or (FCaptionX + FCaptionWidth <= FRectx) then
begin
ASize := 0;
ADstx := 0;
ADsty := 0;
ALines := 0;
end else
begin
if FCaptionWidth + FCaptionX > FRectx then
begin
ADstx := FRectx;
ASrcx := FRectx - FCaptionX;
if FCaptionWidth + FCaptionX >= FRectx + FRectWidth then
ASize := FRectWidth else
ASize := FCaptionWidth - ASrcx;
end;
end;
end;
if (FCaptionY >= FRecty) and (FCaptionY < FRecty + FRectHeight) then
//FCaptionY 在画中 begin
ADsty := FCaptionY;
ASrcy := 0;
if FCaptionY + FCaptionHeight > FRecty + FRectHeight then
ALines := FRecty + FRectHeight - FCaptionY else
ALines := FCaptionHeight;
end else
begin
//y<0 if (FCaptionY >= FRecty + FRectHeight) or (FCaptionY + FCaptionHeight <= FRecty) then
begin
ASize := 0;
ADstx := 0;
ADsty := 0;
ALines := 0;
end else
if FCaptionY + FCaptionHeight > FRecty then
begin
ADsty := FRecty;
ASrcy := FRectY - FCaptionY;
if FCaptionY + FCaptionHeight >= FRecty + FRectHeight then
ALines := FRectHeight else
ALines := FCaptionHeight - ASrcy;
end;
end;
FOldCaptionX := ADstx;
FOldCaptionY := ADsty;
FOldCaptionWidth := ASize;
FOldCaptionHeight := ALines;
end;
//------------------------------------------------------------------------------procedure TxlOSD.InitTempData;var mstmp: TMemoryStream;
begin
if FPTempData <> nil then
begin
FreeMem(FPTempData);
FPTempData := nil;
end;
mstmp := TmemoryStream.Create;
try ConvertOSDFromWord(mstmp);
GetMem(FPTempData, FCaptionWidth * FCaptionHeight);// mstmp.Seek(0, soFrombegin
ning);
mstmp.ReadBuffer(FPTempData^, FCaptionWidth * FCaptionHeight);
finally mstmp.Free;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetVisible(const Value: Boolean);var p: Pointer;
begin
if FInitOSD=False then
Exit;
if FVisible <> Value then
begin
while not FFreedo
begin
end;
FFree := False;
if Value then
begin
ShowOSD();
end else
begin
FTimer.Enabled := False;
p := Ptr(DWORD(FPOldData) + HEADERLONG);
FillChar(p^, FWidth * FHeight, $7F);
end;
FVisible := Value;
WriteData(FPOldData, FSize);
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaptionRect(const Value: TRect);
begin
// FCaptionRect := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetIsUsePanel(const Value: Boolean);
begin
if Value <> FIsUsePanel then
FIsUsePanel := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.MakePanel;var i, j: Integer;
p ,p1, p2: PBYTE;
begin
if not FScrolled then
Exit;
if (FScrollStyle = ssLeftToRight) or (FScrollStyle = ssRightToLeft) then
begin
p := PBYTE(DWORD(FPData) + FOldCaptionY * FWidth);
for i := 0 to FOldCaptionHeight - 1do
begin
p1 := PBYTE(DWORD(p1) + FWidth);
p2 := p1;
if Odd(i) then
begin
for j := 0 to FWidth - 1do
begin
if Odd(j) then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end else
begin
for j := 0 to FWidth - 1do
begin
if not Odd(j) then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end;
end;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.EditWordValue;var i, j: Integer;
p ,p1, p2: PBYTE;
begin
if not FScrolled then
Exit;
if (FScrollStyle = ssLeftToRight) or (FScrollStyle = ssRightToLeft) then
begin
p := PBYTE(DWORD(FPOldData) + HEADERLONG + FOldCaptionY * FWidth + FOldCaptionX);
for i := 0 to FOldCaptionHeight - 1do
begin
p1 := PBYTE(DWORD(p) + i * FWidth);
p2 := p1;
if Odd(i) then
begin
for j := 0 to FOldCaptionWidth - 1do
begin
if Odd(j) then
if p2^ = $7F then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end else
begin
for j := 0 to FOldCaptionWidth - 1do
begin
if not Odd(j) then
if p2^ = $7F then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end;
end;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRectHeight(const Value: Integer);
begin
if Value <> FRectHeight then
FRectHeight := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRectWidth(const Value: Integer);
begin
if Value <> FRectWidth then
FRectWidth := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRectx(const Value: Integer);
begin
if Value <> FRectx then
FRectx := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRecty(const Value: Integer);
begin
if Value <> FRecty then
FRecty := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetIsShowBitmap(const Value: Boolean);
begin
if FIsShowBitmap <> Value then
FIsShowBitmap := Value;
end;
//------------------------------------------------------------------------------function TxlOSD.GetOSDDataFromStream(var ASourceStream, AOutStream: TmemoryStream): Boolean;var bmfh: BITMAPFILEHEADER; bmih: BITMAPINFOHEADER;
pb,pData, pSrc, pDst, pTemp: PBYTE;
i: Integer;
align: Integer;
xx: array[0..3] of Byte;
begin
Result := False;
ASourceStream.Seek(0, soFrombegin
ning);
if AOutStream.Size > 0 then
AOutStream.Clear;
ASourceStream.ReadBuffer(bmfh, SizeOf(bmfh));
ASourceStream.ReadBuffer(bmih, Sizeof(bmih));
if bmih.biBitCount<>8 then
bmih.biBitCount := 7;
Getmem(pData, bmih.biWidth * bmih.biHeight);
Getmem(pTemp, bmih.biWidth * bmih.biHeight);
ASourceStream.ReadBuffer(pData^, bmih.biClrUsed * 4);
pb := pData;
align := bmih.biWidth mod 4;
for i := 0 to bmih.biHeight - 1do
begin
ASourceStream.ReadBuffer(pb^, bmih.biWidth);
pb := PBYTE(DWORD(pb) + bmih.biWidth);
ASourceStream.Read(xx[0], align);
end;
FCaptionWidth := bmih.biWidth;
FCaptionHeight := bmih.biHeight;
FOldCaptionWidth := bmih.biWidth;
FOldCaptionHeight := bmih.biHeight;
pb := pData;
for i := 0 to bmih.biWidth * bmih.biHeight - 1do
begin
pb^ := pb^ and $7F;
pb := PBYTE(DWORD(pb) + 1);
end;
pSrc := PBYTE(DWORD(pData) + bmih.biWidth * bmih.biHeight);
pDst := pTemp;
for i := 0 to bmih.biHeight - 1do
begin
pSrc :=PBYTE(DWORD(pSrc) - bmih.biWidth);
CopyMemory(pdst, psrc, bmih.biWidth); pDst := PBYTE(DWORD(pDst) + bmih.biWidth);
end;
CopyMemory(pData, pTemp, bmih.biWidth * bmih.biHeight);
AOutStream.WriteBuffer(pData^, bmih.biWidth * bmih.biHeight);
FreeMem(pData);
FreeMem(pTemp);
Result := True;
end;
//------------------------------------------------------------------------------//返回OSD可识别的数据流function TxlOSD.ConvertOSDFromWord(var AOutStream: TMemoryStream): Boolean;var stmp: TMemoryStream;
bitmaptmp: TBitmap;
i, j, fIndex: Integer;
m,n: Integer;
begin
Result := False;
if AOutStream.Size > 0 then
AOutStream.Clear;
bitmaptmp := TBitmap.Create;
stmp := TMemoryStream.Create;
try bitmaptmp.PixelFormat := pf8bit;
bitmaptmp.Canvas.Font := FFont;
m := 0;
n := 0;
fIndex := 0;
for i := 0 to FCaption.Count - 1do
begin
n := Length(FCaption.Strings);
if n > m then
begin
m := n;
fIndex := i;
end;
end;
bitmaptmp.Width := bitmaptmp.Canvas.TextWidth(FCaption.Strings[fIndex]);
bitmaptmp.Height := bitmaptmp.Canvas.TextHeight(FCaption.Strings[0]) * FCaption.Count;
j := bitmaptmp.Canvas.TextHeight(FCaption.Strings[0]);
for i := 0 to FCaption.Count - 1do
begin
bitmaptmp.Canvas.TextOut(0, i * j , FCaption.Strings);
end;
bitmaptmp.SaveToStream(stmp);// MakeMoreLinesWords(FCaption.Strings[0], 400, FFont, stmp);
GetOSDDataFromStream(stmp, AOutStream);
finally bitmaptmp.Free;
stmp.Free;
end;
Result := True;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetIsFillGrid(const Value: Boolean);
begin
if Value <> FIsFillGrid then
FIsFillGrid := Value;
end;
//------------------------------------------------------------------------------function TxlOSD.CopyDataToOldData(APSrcData, APDstData: Pointer;
ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer): Boolean;
begin
//图形模拟动画 只变源x坐标,将其一帧的数据复制到FPOldData中去end;
//------------------------------------------------------------------------------function TxlOSD.CopyPaletteToOldData(AmsSrc: TMemoryStream): Boolean;
begin
Result := False;
if AmsSrc.Size <= 0 then
Exit;
AmsSrc.Seek(0, soFrombegin
ning);
if (FPPalette <> nil) and (AmsSrc.Size >= 1024) then
begin
AmsSrc.ReadBuffer(FPPalette^, 1024);
Result := True;
end;
end;
//------------------------------------------------------------------------------function TxlOSD.CopyBitmapDataToOldData: Boolean;var tmpBitmap: TBitmap;
tmpStream: TMemoryStream;
PaletteStream: TMemoryStream;
tmpmsOsd: TMemoryStream;
cx,cy: Integer;
pSrc, p1, p2: Pointer;
pbd: PBYTE;
i, j: Integer;
begin
Result := False;
if FBitmapFile = '' then
Exit;
if not FileExists(FBitmapFile) then
Exit;
tmpBitmap := TBitmap.Create;
tmpStream := TMemoryStream.Create;
PaletteStream := TMemoryStream.Create;
tmpmsOSD := TMemoryStream.Create;
try tmpBitmap.LoadFromFile(FBitmapFile);
tmpBitmap.SaveToStream(tmpStream);
if GetPaletteFromBitmap(tmpStream, PaletteStream) then
begin
CopyPaletteToOldData(PaletteStream);
GetOSDDataFromStream(tmpStream, tmpmsOsd);
if tmpBitmap.Width + FBitmapX > FWidth then
cx := FWidth - FBitmapX else
cx := tmpBitmap.Width;
if tmpBitmap.Height + FBitmapY > FHeight then
cy := FHeight - FBitmapY else
cy := tmpBitmap.Height;
FBitmapWidth := cx;
FBitmapHeight := cy;
GetMem(pSrc, tmpBitmap.Width * tmpBitmap.Height);
tmpmsOsd.Seek(0, soFrombegin
ning);
tmpmsOsd.ReadBuffer(pSrc^, tmpBitmap.Width * tmpBitmap.Height);
p1 := pSrc;
p2 := Ptr(DWORD(FPData) + FBitmapY * FWidth + FBitmapX);
for i := 0 to cy - 1do
begin
CopyMemory(p2, p1, cx);
pbd := PBYTE(DWORD(p2));
if FIsFillGrid then
begin
if Odd(i) then
begin
for j := 0 to cx - 1do
begin
if Odd(j) then
pbd^ := $7F;
pbd := PBYTE(DWORD(pbd) + 1);
end;
end else
begin
for j := 0 to cx - 1do
begin
if not Odd(j) then
pbd^ := $7F;
pbd := PBYTE(DWORD(pbd) + 1);
end;
end;
end;
p1 := Ptr(DWORD(p1) + tmpBitmap.Width);
p2 := Ptr(DWORD(p2) + FWidth);
end;
FreeMem(pSrc);
end;
finally tmpBitmap.Free;
tmpStream.Free;
PaletteStream.Free;
tmpmsOSD.Free;
end;
Result := True;
end;
//------------------------------------------------------------------------------end.
//osd文件头部大小 c_PANELVALUE = $4F;
type TOsdSWMode = (ssSWText,ssSWImage,ssSWTextImage,ssSWNone);
TScrollStyle = (ssLeftToRight, ssRightToLeft, ssTopToBottom, ssBottomToTop,ssNoScroll);
{ TxlOSD } TxlOSD = class (TComponent) private FFree: Boolean;
//是否空闲 FPOldData: Pointer;
//OSD文件指针 FPBakData: Pointer;
//当文字和图片同时显示时,保存的数据。 FPPalette: Pointer;
//调色板指针 FPData: Pointer;
//数据指针 FPTempData: Pointer;
//文字数据指针 FPBitmapData: Pointer;
//位图数据指针 可用于模拟动画 FBitmapFrames: Integer;
//位图帧数 FPlaying: Boolean;
FTimer: TTimer;
FInterval: Cardinal;
pOSD: IRmStream;
pDevice: IRmControlNode;
pMemAlloc: IRmMapMem;
rc_dest: MPEG_OVERLAY_RECT;
FSize: RMuint32;
//OSD文件大小 FCaptionScrolled: Boolean;
FCaptionX: Integer;
FCaptionY: Integer;
FOldCaptionX: Integer;
FOldCaptionY: Integer;
FOldCaptionWidth: Integer;
FOldCaptionHeight: Integer;
FCaptionWidth: Integer;
FCaptionHeight: Integer;
FScrollStyle: TScrollStyle;
FScrollStep: Integer;
FScrolled: Boolean;
FIsUsePanel: Boolean;
FRectx: Integer;
FRecty: Integer;
FRectWidth: Integer;
FRectHeight: Integer;
FBitmapY: Integer;
FBitmapX: Integer;
FCaption: TStringList;
FBitmapFile: string;
FBitmap: TBitmap;
FBitmapWidth: Integer;
FBitmapHeight: Integer;
FActive: Boolean;
FVisible: Boolean;
FHeight: Integer;
FWidth: Integer;
FFont: TFont;
FY: LongWord;
FX: LongWord;
FIsShowBitmap: Boolean;
FIsFillGrid: Boolean;
FlogFont: TlogFont;
FSwMode: TOsdSWMode;
FStretch: Boolean;
FInitOSD : Boolean;
function MakeBitmap(var AmStream: TMemoryStream): Boolean;
procedure ShowOSD;
function WriteToOSD(var AmStream: TMemoryStream): Boolean;
procedure WriteData(pdata: Pointer;
Size: RMuint32);
function InitDevice: Boolean;
procedure ClearOldData(x, y, AWidth, AHeight: Integer);
procedure SetCaptionPos;
procedure CalPos(var ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer);
function CopyFromTempData(ASrcx, ASrcy: Integer;
ASize: Integer;
ALines: Integer;
ADstx, ADsty: Integer): Boolean;
function CopyDataToOldData(APSrcData, APDstData: Pointer;
ASrcx, ASrcy: Integer;
ASize: Integer;
ALines: Integer;
ADstx, ADsty: Integer): Boolean;
procedure MakePanel;
procedure EditWordValue;
procedure OSDTimer(Sender: TObject);
function ConvertOSDFromWord(var AOutStream: TMemoryStream): Boolean;
function GetOSDDataFromStream(var ASourceStream, AOutStream: TmemoryStream): Boolean;
function CopyPaletteToOldData(AmsSrc: TMemoryStream): Boolean;
function CopyBitmapDataToOldData: Boolean;
procedure SetActive(const Value: Boolean);
procedure SetBitmap(const Value: TBitmap);
procedure SetBitmapFile(const Value: string);
procedure SetBitmapX(const Value: Integer);
procedure SetBitmapY(const Value: Integer);
procedure SetCaption(Value: TStringList);
procedure SetCaptionScrolled(const Value: Boolean);
procedure SetCaptionX(const Value: Integer);
procedure SetcaptionY(const Value: Integer);
procedure SetInterval(const Value: Cardinal);
procedure SetScrollStyle(const Value: TScrollStyle);
procedure SetHeight(const Value: Integer);
procedure SetWidth(const Value: Integer);
procedure SetFont(const Value: TFont);
procedure SetX(const Value: LongWord);
procedure SetY(const Value: LongWord);
procedure SetScrollStep(const Value: Integer);
procedure SetScrolled(const Value: Boolean);
procedure SetVisible(const Value: Boolean);
procedure SetCaptionRect(const Value: TRect);
procedure SetIsUsePanel(const Value: Boolean);
procedure SetRectHeight(const Value: Integer);
procedure SetRectWidth(const Value: Integer);
procedure SetRectx(const Value: Integer);
procedure SetRecty(const Value: Integer);
procedure SetIsShowBitmap(const Value: Boolean);
procedure SetIsFillGrid(const Value: Boolean);
public constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
procedure InitTempData;
function Play: Boolean;
function Stop: Boolean;
property Active: Boolean read FActive write SetActive;
property Caption: TStringList read FCaption write SetCaption;
property BitmapFile: string read FBitmapFile write SetBitmapFile;
property Bitmap: TBitmap read FBitmap write SetBitmap;
property ScrollStyle: TScrollStyle read FScrollStyle write SetScrollStyle default ssRightToLeft;
property BitmapX: Integer read FBitmapX write SetBitmapX default 1;
property BitmapY: Integer read FBitmapY write SetBitmapY default 1;
property CaptionX: Integer read FCaptionX write SetCaptionX default 1;
property CaptionY: Integer read FCaptionY write SetCaptionY default 300;
property CaptionScrolled: Boolean read FCaptionScrolled write SetCaptionScrolled;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property Width: Integer read FWidth write SetWidth default 640;
property Height: Integer read FHeight write SetHeight default 480;
property Font: TFont read FFont write SetFont;
property X: LongWord read FX write SetX default 0;
property Y: LongWord read FY write SetY default 0;
property Scrolled: Boolean read FScrolled write SetScrolled default False;
property ScrollStep: Integer read FScrollStep write SetScrollStep default 10;
property Visible: Boolean read FVisible write SetVisible default False;// property IsUsePanel: Boolean read FIsUsePanel write SetIsUsePanel;
property Rectx: Integer read FRectx write SetRectx;
property Recty: Integer read FRecty write SetRecty;
property RectWidth: Integer read FRectWidth write SetRectWidth;
property RectHeight: Integer read FRectHeight write SetRectHeight;// property IsShowBitmap: Boolean read FIsShowBitmap write SetIsShowBitmap;
property IsFillGrid: Boolean read FIsFillGrid write SetIsFillGrid;
property SwMode : TOsdSWMode read FSwMode write FSwMode;
property Stretch : Boolean read FStretch write FStretch;
property isInitOK : Boolean read FInitOSD;
end;
implementation{************************************ TxlOSD ************************************}constructor TxlOSD.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWidth := 650;
FHeight := 525;
FRectx := 0;
FRecty := 0;
FRectWidth := FWidth;
FRectHeight := FHeight;
FBitmapX := 10;
FBitmapY := 20;
FCaptionX := 20;
FCaptionY := 20;
FOldCaptionX := 0;
FOldCaptionY := 200;
FX := 30;
FY := 10;
FScrollStep := 10;
FIsUsePanel := False;
FScrolled := False;
FScrollStyle:= ssTopToBottom;
FSwMode:=ssSWTextImage;
FStretch:=False;
FCaption := TStringList.Create;
FBitmap := TBitmap.Create;
FTimer := TTimer.Create(self);
FTimer.Enabled := False;
FTimer.Interval := 10;
FTimer.OnTimer := OSDTimer;//MovePanel;
FFont := TFont.Create;
FFont.Color := clBlue;
FFont.Size := 20;
FFont.Name := '幼圆';
FIsFillGrid := True;
FPlaying := False;
FVisible := False;
FFree := True;
FInitOSD:=InitDevice();
if FInitOSD=False then
begin
// MessageBox(0,'初试化OSD接口失败!!!','OSD叠加程序',MB_ICONEXCLAMATION);
end;
Play();
end;
//------------------------------------------------------------------------------destructor TxlOSD.Destroy;
begin
Stop();
if FTimer <> nil then
begin
FTimer.Enabled := False;
FTimer.Free;
end;
if FPOldData <> nil then
FreeMem(FPOldData);
if FPBakData <> nil then
FreeMem(FPBakData);
if FPTempData <> nil then
FreeMem(FPTempData);
if FFont <> nil then
FFont.Free;
if FBitmap <> nil then
FBitmap.Free;
if FCaption <> nil then
FCaption.Free;
CoUninitialize();
inherited Destroy;
end;
//------------------------------------------------------------------------------function TxlOSD.MakeBitmap(var AmStream: TMemoryStream): Boolean;var OSDBitmap: TBitmap;
Rect : TRect;
TmpBitmap: TBitmap;
MyJpeg: TJpegImage;
ExtStr : String;
begin
Result := False;
if AmStream.Size > 0 then
AmStream.Clear;
OSDBitmap := TBitmap.Create;
TmpBitmap := TBitmap.Create;
try OSDBitmap.Width := FWidth;
OSDBitmap.Height := FHeight;
OSDBitmap.PixelFormat := pf8bit;
Rect.Top:=0;
Rect.Left:=0;
Rect.Bottom:=OSDBitMap.Height ;
Rect.Right:=OSDBitMap.Width;
OSDBitmap.Canvas.Brush.Color :=clLime;
OSDBitMap.Canvas.FillRect(Rect);
if FIsShowBitmap and Fileexists(BitmapFile) then
begin
ExtStr:=Lowercase(ExtractFileExt(BitmapFile));
if not((ExtStr='.jpg')or(ExtStr='.jpeg')) then
TmpBitmap.LoadFromFile(FBitmapFile) else
begin
MyJpeg:= TJpegImage.Create;
try myjpeg.LoadFromFile(BitmapFile);
TmpBitmap.Assign(myjpeg);
finally myjpeg.Free;
end;
end;
TmpBitmap.Transparent:=True;
if FStretch=False then
OSDBitMap.Canvas.Draw(FBitmapX,FBitmapY,TmpBitmap) else
OSDBitMap.Canvas.StretchDraw(Rect,TmpBitmap);
end;
OSDBitmap.SaveToStream(AmStream);
Result := True;
finally TmpBitmap.Free;
OSDBitmap.Free;
end;
end;
//------------------------------------------------------------------------------//******************初始化********************************function TxlOSD.InitDevice: Boolean;var hr: HRESULT;
pIRmObjectFinder: IRmObjectFinder;
dwTvOutKeep: RMint32;
HwLibVersion, dwTvOut: RMint32;
begin
Result := False;
CoInitialize(nil);
hr := CoCreateInstance( CLSID_RMBASE, nil, CLSCTX_INPROC_SERVER, IID_IRmObjectFinder, pIRmObjectFinder );
if FAILED(hr) then
Exit; hr := pIRmObjectFinder.FindObject(nil, FIRST_AVALIABLE_INSTANCE, CATEGORY_PIN_OSD, IID_IRmStream, pOSD); pIRmObjectFinder := nil;
if FAILED(hr) then
Exit;
pOSD.Reset();
pDevice := nil;
hr := pOSD.QueryInterface(IID_IRmControlNode, pDevice);
if FAILED(hr) then
Exit;
hr := pOSD.QueryInterface(IID_IRmMapMem, pMemAlloc);
if FAILED(hr) then
Exit;
pDevice.GetAttributes(MpegAttrCodeVersion, HwLibVersion);
pDevice.GetAttributes(MpegAttrVideoTv, dwTvOutKeep);
dwTvOut := dwTvOutKeep and (not OUTPUT_OFF);
if HwLibVersion < 9 then
dwTvOut := dwTvOut or SET_TV else
begin
dwTvOut := dwTvOut or SET_TV or $80000000;
dwTvOut := dwTvOut and (not SET_HDTV);
end;
pDevice.SetAttributes(MpegAttrVideoTv, dwTvOut);
Result := True;
end;
//------------------------------------------------------------------------------//*****************清除上一次的滚动文字数据***************procedure TxlOSD.ClearOldData(x, y, AWidth, AHeight: Integer);var p: Pointer;
i: Integer;
begin
CopyMemory(FPData,FPBakData,FSize-HEADERLONG);
p := Ptr(DWORD(FPData) + FWidth * y + x);
for i := 0 to AHeight - 1do
begin
p := Ptr(DWORD(p) + FWidth);
FillChar(P^, AWidth , $7F);
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.OSDTimer(Sender: TObject);var pLine, ptmp: Pointer;
i, ii: Integer;
iX: Integer;
iY: Integer;
p: Pointer;
srcx,srcy,isize,lines,dstx,dsty: Integer;
begin
if (FCaption.Count < 0) or (not FScrolled) or (not FActive) then
begin
FTimer.Enabled := False;
Exit;
end;
if not FFree then
Exit;
if (FSwMode=ssSWImage) then
Exit;
FFree := False;
//if not FIsUsePanel then
ClearOldData(FOldCaptionx, FOldCaptionY, FOldCaptionWidth, FOldCaptionHeight);
//清除上一次内容 SetCaptionPos;
//改变坐标 CalPos(srcx,srcy,isize,lines,dstx,dsty);
//计算出现范围 if FIsUsePanel then
MakePanel();
//加面板条 CopyFromTempData(srcx,srcy,isize,lines,dstx,dsty);
//复制数据 if FIsUsePanel then
EditWordValue();
// WriteData(FPOldData, FSize);
//写OSD数据end;
//------------------------------------------------------------------------------function TxlOSD.Play: Boolean;var ms: TMemoryStream;
begin
Result := False;
if FPlaying then
Exit;
if pOSD <> nil then
begin
Result := FAILED(pOSD.Play);
ms := TMemoryStream.Create;
try FPlaying := True;
FActive := True;
finally ms.Free;
end;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetActive(const Value: Boolean);
begin
if FActive <> Value then
begin
FActive := Value;
if Value then
Play else
Stop;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmap(const Value: TBitmap);
begin
if Value <> nil then
begin
FBitmap.Assign(Value);
FBitmapFile := '';
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmapFile(const Value: string);
begin
if Value <> FBitmapFile then
FBitmapFile := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmapX(const Value: Integer);
begin
if FBitmapX <> Value then
FBitmapX := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetBitmapY(const Value: Integer);
begin
if FBitmapY <> Value then
FBitmapY := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaption(Value: TStringList);
begin
if nil <> Value then
FCaption.Assign(Value);
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaptionScrolled(const Value: Boolean);
begin
if FCaptionScrolled <> Value then
FCaptionScrolled := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaptionX(const Value: Integer);
begin
if FCaptionX <> Value then
begin
FCaptionX := Value;
FOldCaptionX := Value;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetcaptionY(const Value: Integer);
begin
if FCaptionY <> Value then
begin
FCaptionY := Value;
FOldCaptionY := Value;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetFont(const Value: TFont);
begin
if FFont <> nil then
begin
if Value is TFont then
FFont.Assign(Value);
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetHeight(const Value: Integer);
begin
if FHeight <> Value then
FHeight := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetInterval(const Value: Cardinal);
begin
if FInterval <> Value then
begin
FInterval := Value;
FTimer.Interval := Value;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetScrolled(const Value: Boolean);
begin
if FScrolled <> Value then
FScrolled := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetScrollStep(const Value: Integer);
begin
if FScrollStep <> Value then
FScrollStep := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetScrollStyle(const Value: TScrollStyle);
begin
if FScrollStyle <> Value then
FScrollStyle := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetWidth(const Value: Integer);
begin
if FWidth <> Value then
FWidth := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetX(const Value: LongWord);
begin
if FX <> Value then
FX := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetY(const Value: LongWord);
begin
if FY <> Value then
FY := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.ShowOSD;var msSrc, msDest: TMemoryStream;
mslines: TMemoryStream;
begin
msSrc := TMemoryStream.Create;
msDest := TMemoryStream.Create;
mslines := TMemoryStream.Create;
try case FSwMode of ssSWImage : FIsShowBitmap:=True;
ssSWText : FIsShowBitmap:=False;
ssSWTextImage : FIsShowBitmap:=True;
end;
MakeBitmap(msSrc);
Streamrgb2x(msSrc, msDest);
if (FSwMode<>ssSWImage) and (FCaption.Count > 0) then
begin
InitTempData();
end else
FScrolled := False;
WriteToOSD(msDest);
if (FSwMode<>ssSWImage) and (FPTempData <> nil) and (not Scrolled) then
CopyFromTempData(0, 0, FOldCaptionWidth, FOldCaptionHeight, FOldCaptionX, FOldCaptionY);
WriteData(FPOldData, FSize);
finally msSrc.Free;
msDest.Free;
mslines.Free;
end;
FVisible := True;
FTimer.Enabled := FScrolled;
end;
//------------------------------------------------------------------------------function TxlOSD.Stop: Boolean;
begin
Result := False;
if not FPlaying then
Exit;
FTimer.Enabled := False;
while not FFreedo
begin
end;
FFree := False;
if pOSD <> nil then
begin
Result := FAILED(pOSD.Stop);
if pDevice <> nil then
//pDevice.SetAttributes(MpegAttrVideoTv,dwTvOutKeep) pDevice.SetAttributes(MpegAttrOsdOFF,1);
FActive := False;
FPlaying := False;
FVisible := False;
end;
end;
//------------------------------------------------------------------------------//*****************写入OSD数据到pDevice中*************************procedure TxlOSD.WriteData(pdata: Pointer;
Size: RMuint32);var hdr: HEADER;
ovr: RMOVERLAPIO;
begin
FillChar(hdr, Sizeof(hdr), 0);
hdr.multi.Count := 1;
hdr.multi.Size := SizeOf(HEADER);
hdr.header.Size := SizeOf(RMSTREAM_HEADER);
hdr.header.pData := pdata;
hdr.header.FrameExtent := Size;
ovr.do_not_use[0] := 0;
ovr.do_not_use[1] := 0;
ovr.do_not_use[2] := 0;
ovr.do_not_use[3] := 0;
ovr.hEvent := CreateEvent(nil, True, False, nil);
pOSD.Write(@hdr.multi, ovr);
WaitForSingleObject(ovr.hEvent,10000);
pDevice.SetAttributes(MpegAttrOsdDest, LongInt(@rc_dest));
pDevice.SetAttributes(MpegAttrOsdON, 1);
CloseHandle(ovr.hEvent);
FFree := True;
end;
//------------------------------------------------------------------------------//************转换成OSD数据**************************function TxlOSD.WriteToOSD(var AmStream: TMemoryStream): Boolean;var phys: Pointer;
hdr: HEADER;
Buff_8: array[0..7] of Byte;
pshared: Pointer;
i,j: Integer;
b: Boolean;
p,ptmp: PBYTE;
begin
Result := False;
AmStream.Seek(0, soFrombegin
ning);
AmStream.ReadBuffer(Buff_8[0], SizeOf(Buff_8)); // 从前8个字节中算出图形大小Width, Height FSize := (buff_8[1] shl (8*2)) or (buff_8[2] shl 8) or buff_8[3];
rc_dest.X := FX;
rc_dest.Y := FY;
rc_dest.cX := (buff_8[4] shl 8) or buff_8[5];
rc_dest.cY := (buff_8[6] shl 8) or buff_8[7]; // 重新读取所有的数据 if FSize = 0 then
Exit;
AmStream.Seek(0, soFrombegin
ning);
if FPoldData <> nil then
begin
FreeMem(FPOldData);
FPOldData := nil;
end;
if FPBakData <> nil then
begin
FreeMem(FPBakData);
FPBakData := nil;
end;
Getmem(pshared, FSize);
Getmem(FPOldData, FSize);
if pshared = nil then
Exit;
AmStream.ReadBuffer(pshared^, FSize);
if FIsFillGrid then
begin
for i := 0 to FHeight - 1do
begin
p := PBYTE(DWORD(pshared) + 1032 + i * FWidth);
ptmp := p;
if Odd(i) then
for j := 0 to FWidth - 1do
begin
if Odd(j) then
ptmp^ := $7F;
ptmp := PBYTE(DWORD(p) + j);
end else
for j := 0 to FWidth - 1do
begin
if not Odd(j) then
ptmp^ := $7F;
ptmp := PBYTE(DWORD(p) + j);
end;
end;
end;
WriteData(pshared, FSize);
CopyMemory(FPOldData, pshared, FSize);
FPPalette := Pointer(DWORD(FPOldData) + 8);
FPData := Pointer(DWORD(FPOldData) + HEADERLONG);
FreeMem(pshared);
Getmem(FPBakData, FSize-HEADERLONG);
CopyMemory(FPBakData,FPData, FSize-HEADERLONG);
Result := True;
end;
//------------------------------------------------------------------------------//***************复制数据到OSD数据中****************************function TxlOSD.CopyFromTempData(ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer): Boolean;var pSrc, pDst: Pointer;
i, j, ii: Integer;
b: Boolean;
ptmp: PBYTE;
begin
Result := False;
pSrc := Pointer(DWORD(FPTempData) + ASrcy * FCaptionWidth + ASrcx);
pDst := Pointer(DWORD(FPOldData) + HEADERLONG + ADsty * FWidth + ADstx);
for i := 0 to ALines - 1do
begin
CopyMemory(pDst, pSrc, ASize);
pSrc := Ptr(DWORD(pSrc) + FCaptionWidth);
pDst := Ptr(DWORD(pDst) + FWidth);
end;
Result := True;
end;
//------------------------------------------------------------------------------//*************改变滚动文字的坐标*************************procedure TxlOSD.SetCaptionPos;
begin
case FScrollStyle of ssLeftToRight: begin
if FCaptionX >= FRectx + FRectWidth then
FCaptionX := FRectx - FCaptionWidth + 10 else
Inc(FCaptionX, FScrollStep);
end;
ssRightToLeft: begin
if FCaptionX <= FRectx - FCaptionWidth then
FCaptionX := FRectx + FRectWidth - 10 else
Dec(FCaptionX, FScrollStep);
end;
ssTopToBottom: begin
if FCaptionY >= FRecty + FRectHeight then
FCaptionY := FRecty - FCaptionHeight + 10 else
Inc(FCaptionY, FScrollStep);
end;
ssBottomToTop: begin
if FCaptionY <= FRecty - FCaptionHeight then
FCaptionY := FRecty + FRectHeight - 10 else
Dec(FCaptionY, FScrollStep);
end;
end;
end;
//------------------------------------------------------------------------------//************计算要复制的数据cx,cy, 坐标**************************procedure TxlOSD.CalPos(var ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer);
begin
if (FCaptionX >= FRectx) and (FCaptionX < FRectx + FRectWidth) then
//FCaptionX 在画中 begin
ADstx := FCaptionX;
ASrcx := 0;
if FCaptionX + FCaptionWidth >= FRectx + FRectWidth then
ASize := FRectx + FRectWidth - FCaptionX else
ASize := FCaptionWidth;
end else
begin
if (FCaptionX >= FRectx + FRectWidth) or (FCaptionX + FCaptionWidth <= FRectx) then
begin
ASize := 0;
ADstx := 0;
ADsty := 0;
ALines := 0;
end else
begin
if FCaptionWidth + FCaptionX > FRectx then
begin
ADstx := FRectx;
ASrcx := FRectx - FCaptionX;
if FCaptionWidth + FCaptionX >= FRectx + FRectWidth then
ASize := FRectWidth else
ASize := FCaptionWidth - ASrcx;
end;
end;
end;
if (FCaptionY >= FRecty) and (FCaptionY < FRecty + FRectHeight) then
//FCaptionY 在画中 begin
ADsty := FCaptionY;
ASrcy := 0;
if FCaptionY + FCaptionHeight > FRecty + FRectHeight then
ALines := FRecty + FRectHeight - FCaptionY else
ALines := FCaptionHeight;
end else
begin
//y<0 if (FCaptionY >= FRecty + FRectHeight) or (FCaptionY + FCaptionHeight <= FRecty) then
begin
ASize := 0;
ADstx := 0;
ADsty := 0;
ALines := 0;
end else
if FCaptionY + FCaptionHeight > FRecty then
begin
ADsty := FRecty;
ASrcy := FRectY - FCaptionY;
if FCaptionY + FCaptionHeight >= FRecty + FRectHeight then
ALines := FRectHeight else
ALines := FCaptionHeight - ASrcy;
end;
end;
FOldCaptionX := ADstx;
FOldCaptionY := ADsty;
FOldCaptionWidth := ASize;
FOldCaptionHeight := ALines;
end;
//------------------------------------------------------------------------------procedure TxlOSD.InitTempData;var mstmp: TMemoryStream;
begin
if FPTempData <> nil then
begin
FreeMem(FPTempData);
FPTempData := nil;
end;
mstmp := TmemoryStream.Create;
try ConvertOSDFromWord(mstmp);
GetMem(FPTempData, FCaptionWidth * FCaptionHeight);// mstmp.Seek(0, soFrombegin
ning);
mstmp.ReadBuffer(FPTempData^, FCaptionWidth * FCaptionHeight);
finally mstmp.Free;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetVisible(const Value: Boolean);var p: Pointer;
begin
if FInitOSD=False then
Exit;
if FVisible <> Value then
begin
while not FFreedo
begin
end;
FFree := False;
if Value then
begin
ShowOSD();
end else
begin
FTimer.Enabled := False;
p := Ptr(DWORD(FPOldData) + HEADERLONG);
FillChar(p^, FWidth * FHeight, $7F);
end;
FVisible := Value;
WriteData(FPOldData, FSize);
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetCaptionRect(const Value: TRect);
begin
// FCaptionRect := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetIsUsePanel(const Value: Boolean);
begin
if Value <> FIsUsePanel then
FIsUsePanel := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.MakePanel;var i, j: Integer;
p ,p1, p2: PBYTE;
begin
if not FScrolled then
Exit;
if (FScrollStyle = ssLeftToRight) or (FScrollStyle = ssRightToLeft) then
begin
p := PBYTE(DWORD(FPData) + FOldCaptionY * FWidth);
for i := 0 to FOldCaptionHeight - 1do
begin
p1 := PBYTE(DWORD(p1) + FWidth);
p2 := p1;
if Odd(i) then
begin
for j := 0 to FWidth - 1do
begin
if Odd(j) then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end else
begin
for j := 0 to FWidth - 1do
begin
if not Odd(j) then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end;
end;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.EditWordValue;var i, j: Integer;
p ,p1, p2: PBYTE;
begin
if not FScrolled then
Exit;
if (FScrollStyle = ssLeftToRight) or (FScrollStyle = ssRightToLeft) then
begin
p := PBYTE(DWORD(FPOldData) + HEADERLONG + FOldCaptionY * FWidth + FOldCaptionX);
for i := 0 to FOldCaptionHeight - 1do
begin
p1 := PBYTE(DWORD(p) + i * FWidth);
p2 := p1;
if Odd(i) then
begin
for j := 0 to FOldCaptionWidth - 1do
begin
if Odd(j) then
if p2^ = $7F then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end else
begin
for j := 0 to FOldCaptionWidth - 1do
begin
if not Odd(j) then
if p2^ = $7F then
p2^ := c_PANELVALUE;
p2 := PBYTE(DWORD(p2) + 1);
end;
end;
end;
end;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRectHeight(const Value: Integer);
begin
if Value <> FRectHeight then
FRectHeight := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRectWidth(const Value: Integer);
begin
if Value <> FRectWidth then
FRectWidth := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRectx(const Value: Integer);
begin
if Value <> FRectx then
FRectx := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetRecty(const Value: Integer);
begin
if Value <> FRecty then
FRecty := Value;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetIsShowBitmap(const Value: Boolean);
begin
if FIsShowBitmap <> Value then
FIsShowBitmap := Value;
end;
//------------------------------------------------------------------------------function TxlOSD.GetOSDDataFromStream(var ASourceStream, AOutStream: TmemoryStream): Boolean;var bmfh: BITMAPFILEHEADER; bmih: BITMAPINFOHEADER;
pb,pData, pSrc, pDst, pTemp: PBYTE;
i: Integer;
align: Integer;
xx: array[0..3] of Byte;
begin
Result := False;
ASourceStream.Seek(0, soFrombegin
ning);
if AOutStream.Size > 0 then
AOutStream.Clear;
ASourceStream.ReadBuffer(bmfh, SizeOf(bmfh));
ASourceStream.ReadBuffer(bmih, Sizeof(bmih));
if bmih.biBitCount<>8 then
bmih.biBitCount := 7;
Getmem(pData, bmih.biWidth * bmih.biHeight);
Getmem(pTemp, bmih.biWidth * bmih.biHeight);
ASourceStream.ReadBuffer(pData^, bmih.biClrUsed * 4);
pb := pData;
align := bmih.biWidth mod 4;
for i := 0 to bmih.biHeight - 1do
begin
ASourceStream.ReadBuffer(pb^, bmih.biWidth);
pb := PBYTE(DWORD(pb) + bmih.biWidth);
ASourceStream.Read(xx[0], align);
end;
FCaptionWidth := bmih.biWidth;
FCaptionHeight := bmih.biHeight;
FOldCaptionWidth := bmih.biWidth;
FOldCaptionHeight := bmih.biHeight;
pb := pData;
for i := 0 to bmih.biWidth * bmih.biHeight - 1do
begin
pb^ := pb^ and $7F;
pb := PBYTE(DWORD(pb) + 1);
end;
pSrc := PBYTE(DWORD(pData) + bmih.biWidth * bmih.biHeight);
pDst := pTemp;
for i := 0 to bmih.biHeight - 1do
begin
pSrc :=PBYTE(DWORD(pSrc) - bmih.biWidth);
CopyMemory(pdst, psrc, bmih.biWidth); pDst := PBYTE(DWORD(pDst) + bmih.biWidth);
end;
CopyMemory(pData, pTemp, bmih.biWidth * bmih.biHeight);
AOutStream.WriteBuffer(pData^, bmih.biWidth * bmih.biHeight);
FreeMem(pData);
FreeMem(pTemp);
Result := True;
end;
//------------------------------------------------------------------------------//返回OSD可识别的数据流function TxlOSD.ConvertOSDFromWord(var AOutStream: TMemoryStream): Boolean;var stmp: TMemoryStream;
bitmaptmp: TBitmap;
i, j, fIndex: Integer;
m,n: Integer;
begin
Result := False;
if AOutStream.Size > 0 then
AOutStream.Clear;
bitmaptmp := TBitmap.Create;
stmp := TMemoryStream.Create;
try bitmaptmp.PixelFormat := pf8bit;
bitmaptmp.Canvas.Font := FFont;
m := 0;
n := 0;
fIndex := 0;
for i := 0 to FCaption.Count - 1do
begin
n := Length(FCaption.Strings);
if n > m then
begin
m := n;
fIndex := i;
end;
end;
bitmaptmp.Width := bitmaptmp.Canvas.TextWidth(FCaption.Strings[fIndex]);
bitmaptmp.Height := bitmaptmp.Canvas.TextHeight(FCaption.Strings[0]) * FCaption.Count;
j := bitmaptmp.Canvas.TextHeight(FCaption.Strings[0]);
for i := 0 to FCaption.Count - 1do
begin
bitmaptmp.Canvas.TextOut(0, i * j , FCaption.Strings);
end;
bitmaptmp.SaveToStream(stmp);// MakeMoreLinesWords(FCaption.Strings[0], 400, FFont, stmp);
GetOSDDataFromStream(stmp, AOutStream);
finally bitmaptmp.Free;
stmp.Free;
end;
Result := True;
end;
//------------------------------------------------------------------------------procedure TxlOSD.SetIsFillGrid(const Value: Boolean);
begin
if Value <> FIsFillGrid then
FIsFillGrid := Value;
end;
//------------------------------------------------------------------------------function TxlOSD.CopyDataToOldData(APSrcData, APDstData: Pointer;
ASrcx, ASrcy, ASize, ALines, ADstx, ADsty: Integer): Boolean;
begin
//图形模拟动画 只变源x坐标,将其一帧的数据复制到FPOldData中去end;
//------------------------------------------------------------------------------function TxlOSD.CopyPaletteToOldData(AmsSrc: TMemoryStream): Boolean;
begin
Result := False;
if AmsSrc.Size <= 0 then
Exit;
AmsSrc.Seek(0, soFrombegin
ning);
if (FPPalette <> nil) and (AmsSrc.Size >= 1024) then
begin
AmsSrc.ReadBuffer(FPPalette^, 1024);
Result := True;
end;
end;
//------------------------------------------------------------------------------function TxlOSD.CopyBitmapDataToOldData: Boolean;var tmpBitmap: TBitmap;
tmpStream: TMemoryStream;
PaletteStream: TMemoryStream;
tmpmsOsd: TMemoryStream;
cx,cy: Integer;
pSrc, p1, p2: Pointer;
pbd: PBYTE;
i, j: Integer;
begin
Result := False;
if FBitmapFile = '' then
Exit;
if not FileExists(FBitmapFile) then
Exit;
tmpBitmap := TBitmap.Create;
tmpStream := TMemoryStream.Create;
PaletteStream := TMemoryStream.Create;
tmpmsOSD := TMemoryStream.Create;
try tmpBitmap.LoadFromFile(FBitmapFile);
tmpBitmap.SaveToStream(tmpStream);
if GetPaletteFromBitmap(tmpStream, PaletteStream) then
begin
CopyPaletteToOldData(PaletteStream);
GetOSDDataFromStream(tmpStream, tmpmsOsd);
if tmpBitmap.Width + FBitmapX > FWidth then
cx := FWidth - FBitmapX else
cx := tmpBitmap.Width;
if tmpBitmap.Height + FBitmapY > FHeight then
cy := FHeight - FBitmapY else
cy := tmpBitmap.Height;
FBitmapWidth := cx;
FBitmapHeight := cy;
GetMem(pSrc, tmpBitmap.Width * tmpBitmap.Height);
tmpmsOsd.Seek(0, soFrombegin
ning);
tmpmsOsd.ReadBuffer(pSrc^, tmpBitmap.Width * tmpBitmap.Height);
p1 := pSrc;
p2 := Ptr(DWORD(FPData) + FBitmapY * FWidth + FBitmapX);
for i := 0 to cy - 1do
begin
CopyMemory(p2, p1, cx);
pbd := PBYTE(DWORD(p2));
if FIsFillGrid then
begin
if Odd(i) then
begin
for j := 0 to cx - 1do
begin
if Odd(j) then
pbd^ := $7F;
pbd := PBYTE(DWORD(pbd) + 1);
end;
end else
begin
for j := 0 to cx - 1do
begin
if not Odd(j) then
pbd^ := $7F;
pbd := PBYTE(DWORD(pbd) + 1);
end;
end;
end;
p1 := Ptr(DWORD(p1) + tmpBitmap.Width);
p2 := Ptr(DWORD(p2) + FWidth);
end;
FreeMem(pSrc);
end;
finally tmpBitmap.Free;
tmpStream.Free;
PaletteStream.Free;
tmpmsOSD.Free;
end;
Result := True;
end;
//------------------------------------------------------------------------------end.