UAlphaRenderer.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:7k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. //------------------------------------------------------------------------------
  2. // File:              UAlphaRenderer.pas
  3. // Original file(s): AlphaRenderer.h, AlphaRenderer.c
  4. //
  5. // Desc: DirectShow sample filter: Alpha Renderer
  6. //
  7. // Portions created by Microsoft are
  8. // Copyright (c) Microsoft Corporation.  All rights reserved.
  9. //------------------------------------------------------------------------------
  10. {
  11.   @abstract(Alpha Renderer Sample Filter from DS SDK)
  12.   @author(Andriy Nevhasymyy: a.n@email.com)
  13.   @created(Aug 11, 2003)
  14.   @lastmod(Aug 12, 2003)
  15. }
  16. unit UAlphaRenderer;
  17. interface
  18. uses
  19.   BaseClass, DirectShow9,
  20.   Windows, SysUtils, Classes, ActiveX;
  21. const
  22.   CLSID_AlphaRenderer: TGUID = '{A63A8661-EEB3-4036-9964-EACD50973E4F}';
  23. type
  24.   TBCAlphaRenderer = class(TBCBaseRenderer)
  25.   private
  26.     FWnd      : HWND;
  27.     FDC       : HDC;
  28.     FWidth    : Integer;
  29.     FHeight   : Integer;
  30.     FBmi      : TBITMAPINFOHEADER;
  31.     FCheckers : PDWord;
  32.     procedure _Clear;
  33.   public
  34.     constructor Create(ObjName: String; Unk: IUnknown; out hr : HResult);
  35.     constructor CreateFromFactory(Factory: TBCClassFactory;
  36.       const Controller: IUnknown); override;
  37.     destructor Destroy; override;
  38.     // make sure media type is what we want
  39.     //
  40.     function CheckMediaType(MediaType: PAMMediaType): HResult; override;
  41.     // have to ovverride this
  42.     //
  43.     function DoRenderSample(MediaSample: IMediaSample): HResult; override;
  44.     // have to override this
  45.     //
  46.     function SetMediaType(MediaType: PAMMediaType): HResult; override;
  47.     // override these to receive indication of when we change
  48.     // to Pause/Play (Active) or Stop (Inactive) state.
  49.     function Active: HResult; override;
  50.     function Inactive: HResult; override;
  51.   end;
  52. implementation
  53. {$BOOLEVAL OFF}
  54. //
  55. // CreateInstance
  56. //
  57. constructor TBCAlphaRenderer.Create(ObjName: String; Unk: IUnknown;
  58.   out hr: HResult);
  59. begin
  60.   inherited Create(CLSID_AlphaRenderer, 'AlphaRenderer', Unk, hr);
  61.   FWnd      := 0;
  62.   FDC       := 0;
  63.   FWidth    := 0;
  64.   FHeight   := 0;
  65.   FCheckers := nil;
  66. end;
  67. constructor TBCAlphaRenderer.CreateFromFactory(Factory: TBCClassFactory;
  68.   const Controller: IUnknown);
  69. var
  70.   hr: HRESULT;
  71. begin
  72.   Create(Factory.Name, Controller, hr);
  73. end;
  74. destructor TBCAlphaRenderer.Destroy;
  75. begin
  76.   OutputDebugString('TBCAlphaRenderer.Destroy');
  77.   _Clear;
  78.   inherited Destroy;
  79. end;
  80. // throw away the window and the checkerboard pattern
  81. //
  82. procedure TBCAlphaRenderer._Clear;
  83. begin
  84.   if (FDC <> 0) then
  85.   begin
  86.     ReleaseDC(FWnd, FDC);
  87.     FDC := 0;
  88.   end;
  89.   if (FWnd <> 0) then
  90.   begin
  91.     DestroyWindow(FWnd);
  92.     FWnd := 0;
  93.   end;
  94.   if Assigned(FCheckers) then
  95.   begin
  96.     FreeMem(FCheckers);
  97.     FCheckers := nil;
  98.   end;
  99. end;
  100. // Called when we go paused or running
  101. function TBCAlphaRenderer.Active: HResult;
  102. begin
  103.   // Make our renderer window visible
  104.   ShowWindow(FWnd, SW_SHOWNORMAL);
  105.   Result := inherited Active;
  106. end;
  107. // Called when we go into a stopped state
  108. function TBCAlphaRenderer.Inactive: HResult;
  109. begin
  110.   // Make our renderer window visible
  111.   ShowWindow(FWnd, SW_HIDE);
  112.   Result := inherited Inactive;
  113. end;
  114. // make sure media type is what we want
  115. //
  116. function TBCAlphaRenderer.CheckMediaType(MediaType: PAMMediaType): HResult;
  117. var
  118.   VIH: PVIDEOINFOHEADER;
  119. begin
  120.   if (MediaType = nil) then
  121.   begin
  122.     Result := E_POINTER;
  123.     Exit;
  124.   end;
  125.   // the major type must match
  126.   if (not IsEqualGUID(MediaType.majortype, MEDIATYPE_Video)) or
  127.     // the sub type must match
  128.   (not IsEqualGUID(MediaType.subtype, MEDIASUBTYPE_ARGB32)) or
  129.     // the format must match
  130.   (not IsEqualGUID(MediaType.formattype, FORMAT_VideoInfo)) then
  131.   begin
  132.     Result := E_INVALIDARG;
  133.     Exit;
  134.   end;
  135.   VIH := PVIDEOINFOHEADER(MediaType.pbFormat);
  136.   Assert(Assigned(VIH));
  137.   // we could do more here to ensure the image is right-side up
  138.   // by looking at the bitmap info header in the VIDEOINFO struct
  139.   //
  140.   Result := NOERROR;
  141. end;
  142. // have to ovverride this, render the incoming sample onto the checkerboard
  143. //
  144. function TBCAlphaRenderer.DoRenderSample(MediaSample: IMediaSample): HResult;
  145. var
  146.   Bits: PByte;
  147.   len, x: Integer;
  148.   Source, Checkers: PRGBQUAD;
  149.   d: RGBQUAD;
  150. begin
  151.   if (MediaSample = nil) then
  152.   begin
  153.     Result := E_POINTER;
  154.     Exit;
  155.   end;
  156.   MediaSample.GetPointer(Bits);
  157.   len := MediaSample.GetActualDataLength;
  158.   Assert(len = FWidth * FHeight * SizeOf(DWord));
  159.   // now blend checkerboard into bits before we blit them
  160.   // the incoming source
  161.   //
  162.   Source := PRGBQUAD(Bits);
  163.   // the checkerboard buffer
  164.   //
  165.   Checkers := PRGBQUAD(FCheckers);
  166.   // blend them
  167.   //
  168.   for x := 0 to FWidth * FHeight - 1 do
  169.   begin
  170.     d.rgbRed := Byte((Source.rgbRed * Source.rgbReserved div 256 +
  171.       Checkers.rgbRed * (256 - Source.rgbReserved) div 256));
  172.     d.rgbGreen := Byte((Source.rgbGreen * Source.rgbReserved div 256 +
  173.       Checkers.rgbGreen * (256 - Source.rgbReserved) div 256));
  174.     d.rgbBlue := Byte((Source.rgbBlue * Source.rgbReserved div 256 +
  175.       Checkers.rgbBlue * (256 - Source.rgbReserved) div 256));
  176.     CopyMemory(Source, @d, SizeOf(RGBQUAD));
  177.     Inc(Source);
  178.     Inc(Checkers);
  179.   end;
  180.   // put the bits into the window
  181.   //
  182.   StretchDIBits(FDC,
  183.     0, 0, FWidth, FHeight,
  184.     0, 0, FWidth, FHeight,
  185.     Bits, PBitmapInfo(@FBMI)^,
  186.     DIB_RGB_COLORS, SRCCOPY);
  187.   Result := NOERROR;
  188. end;
  189. // Must override this. We create the window here
  190. //
  191. function TBCAlphaRenderer.SetMediaType(MediaType: PAMMediaType): HResult;
  192. var
  193.   VIH: PVIDEOINFOHEADER;
  194.   Width, Height, x, y: Integer;
  195.   OnOff: Boolean;
  196.   p: PDWord;
  197. begin
  198.   if (MediaType = nil) then
  199.   begin
  200.     Result := E_POINTER;
  201.     Exit;
  202.   end;
  203.   _Clear;
  204.   // we know it's a VIDEOINFOHEADER, since we demanded one
  205.   // in CheckMediaType
  206.   //
  207.   VIH := PVIDEOINFOHEADER(MediaType.pbFormat);
  208.   if (VIH = nil) then
  209.   begin
  210.     Result := E_UNEXPECTED;
  211.     Exit;
  212.   end;
  213.   FWidth  := VIH.bmiHeader.biWidth;
  214.   Width   := FWidth;
  215.   FHeight := VIH.bmiHeader.biHeight;
  216.   Height  := FHeight;
  217.   // save this off for lookin' at it later
  218.   //
  219.   CopyMemory(@FBMI, @VIH.bmiHeader, SizeOf(TBitmapInfoHeader));
  220.   //FBMI := @VIH.bmiHeader;
  221.   // create the window
  222.   //
  223.   FWnd := CreateWindow(
  224.     'STATIC', 'Video Renderer',
  225.     WS_POPUP, // NOT Visible
  226.     0, 0, Width, Height,
  227.     0, 0, hInstance, nil
  228.     );
  229.   // get the DC
  230.   //
  231.   FDC := GetDC(FWnd);
  232.   // create a checker buffer
  233.   //
  234.   try
  235.     GetMem(FCheckers, SizeOf(DWord) * Width * Height);
  236.     // draw the checkers
  237.     //
  238.     for x := 0 to Width - 1 do
  239.       for y := 0 to Height - 1 do
  240.       begin
  241.         OnOff := False;
  242.         if (x div 8 mod 2 = 0) then
  243.           OnOff := not OnOff;
  244.         if (y div 8 mod 2 = 0) then
  245.           OnOff := not OnOff;
  246.         p := FCheckers;
  247.         Inc(p, y * Width);
  248.         Inc(p, x);
  249.         if not OnOff then
  250.           p^ := 0
  251.         else
  252.           p^ := $FFFFFF;
  253.       end;
  254.     Result := NOERROR;
  255.   except
  256.     Result := E_OUTOFMEMORY;
  257.   end;
  258. end;
  259. initialization
  260.   // provide an entry in the CFactoryTemplate array
  261.   TBCClassFactory.CreateFilter(TBCAlphaRenderer, '_ AlphaRenderer',
  262.     CLSID_AlphaRenderer, CLSID_LegacyAmFilterCategory, MERIT_DO_NOT_USE,
  263.     0, nil
  264.     );
  265. end.