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

Delphi控件源码

开发平台:

Delphi

  1.     (*********************************************************************
  2.      *                                                                   *
  3.      * The contents of this file are used with permission, subject to    *
  4.      * the Mozilla Public License Version 1.1 (the "License"); you may   *
  5.      * not use this file except in compliance with the License. You may  *
  6.      * obtain a copy of the License at                                   *
  7.      * http://www.mozilla.org/MPL/MPL-1.1.html                           *
  8.      *                                                                   *
  9.      * Software distributed under the License is distributed on an       *
  10.      * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or    *
  11.      * implied. See the License for the specific language governing      *
  12.      * rights and limitations under the License.                         *
  13.      *                                                                   *
  14.      * (C) 2004 Milenko Mitrovic <dcoder@dsp-worx.de>                    *
  15.      *                                                                   *
  16.      *********************************************************************)
  17. unit VidRenderer;
  18. interface
  19. uses
  20.   BaseClass, DirectShow9, Windows, SysUtils, Classes, Forms, ActiveX, Graphics,
  21.   Messages, formRenderer;
  22. const
  23.   CLSID_DelphiVideoRenderer: TGUID = '{DB2CF44E-B672-4F18-B407-9169FE84D1EB}';
  24.   DEFWIDTH = 320;                    // Initial window width
  25.   DEFHEIGHT = 240;                   // Initial window height
  26. type
  27.   TVideoRenderer = class(TBCBaseVideoRenderer, IPersist, IVideoWindow, IDispatch,
  28.                          IBasicVideo, IBasicVideo2, IAMFilterMiscFlags)
  29.   private
  30.     fAutoShow : Boolean;
  31.     fDispatch : TBCBaseDispatch;
  32.     fFormat   : TVideoInfoHeader;
  33.     fRenderer : TfrmRenderer;
  34.   public
  35.     constructor Create(ObjName: String; Unk: IUnknown; out hr : HResult);
  36.     constructor CreateFromFactory(Factory: TBCClassFactory; const Controller: IUnknown); override;
  37.     destructor Destroy; override;
  38.     function CheckMediaType(MediaType: PAMMediaType): HResult; override;
  39.     function DoRenderSample(MediaSample: IMediaSample): HResult; override;
  40.     procedure OnReceiveFirstSample(MediaSample: IMediaSample); override;
  41.     function SetMediaType(MediaType: PAMMediaType): HResult; override;
  42.     function Active: HResult; override;
  43.     function Inactive: HResult; override;
  44.     (*** IDispatch methods ***)
  45.     function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
  46.     function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
  47.     function GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
  48.     function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
  49.     (*** IVideoWindow methods ***)
  50.     function put_Caption(strCaption: WideString): HResult; stdcall;
  51.     function get_Caption(out strCaption: WideString): HResult; stdcall;
  52.     function put_WindowStyle(WindowStyle: Longint): HResult; stdcall;
  53.     function get_WindowStyle(out WindowStyle: Longint): HResult; stdcall;
  54.     function put_WindowStyleEx(WindowStyleEx: Longint): HResult; stdcall;
  55.     function get_WindowStyleEx(out WindowStyleEx: Longint): HResult; stdcall;
  56.     function put_AutoShow(AutoShow: LongBool): HResult; stdcall;
  57.     function get_AutoShow(out AutoShow: LongBool): HResult; stdcall;
  58.     function put_WindowState(WindowState: Longint): HResult; stdcall;
  59.     function get_WindowState(out WindowState: Longint): HResult; stdcall;
  60.     function put_BackgroundPalette(BackgroundPalette: Longint): HResult; stdcall;
  61.     function get_BackgroundPalette(out pBackgroundPalette: Longint): HResult; stdcall;
  62.     function put_Visible(Visible: LongBool): HResult; stdcall;
  63.     function get_Visible(out pVisible: LongBool): HResult; stdcall;
  64.     function put_Left(Left: Longint): HResult; stdcall;
  65.     function get_Left(out pLeft: Longint): HResult; stdcall;
  66.     function put_Width(Width: Longint): HResult; stdcall;
  67.     function get_Width(out pWidth: Longint): HResult; stdcall;
  68.     function put_Top(Top: Longint): HResult; stdcall;
  69.     function get_Top(out pTop: Longint): HResult; stdcall;
  70.     function put_Height(Height: Longint): HResult; stdcall;
  71.     function get_Height(out pHeight: Longint): HResult; stdcall;
  72.     function put_Owner(Owner: OAHWND): HResult; stdcall;
  73.     function get_Owner(out Owner: OAHWND): HResult; stdcall;
  74.     function put_MessageDrain(Drain: OAHWND): HResult; stdcall;
  75.     function get_MessageDrain(out Drain: OAHWND): HResult; stdcall;
  76.     function get_BorderColor(out Color: Longint): HResult; stdcall;
  77.     function put_BorderColor(Color: Longint): HResult; stdcall;
  78.     function get_FullScreenMode(out FullScreenMode: LongBool): HResult; stdcall;
  79.     function put_FullScreenMode(FullScreenMode: LongBool): HResult; stdcall;
  80.     function SetWindowForeground(Focus: Longint): HResult; stdcall;
  81.     function NotifyOwnerMessage(hwnd: Longint; uMsg, wParam, lParam: Longint): HResult; stdcall;
  82.     function SetWindowPosition(Left, Top, Width, Height: Longint): HResult; stdcall;
  83.     function GetWindowPosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  84.     function GetMinIdealImageSize(out pWidth, pHeight: Longint): HResult; stdcall;
  85.     function GetMaxIdealImageSize(out pWidth, pHeight: Longint): HResult; stdcall;
  86.     function GetRestorePosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  87.     function HideCursor(HideCursor: LongBool): HResult; stdcall;
  88.     function IsCursorHidden(out CursorHidden: LongBool): HResult; stdcall;
  89.     (*** IBasicVideo methods ***)
  90.     function get_AvgTimePerFrame(out pAvgTimePerFrame: TRefTime): HResult; stdcall;
  91.     function get_BitRate(out pBitRate: Longint): HResult; stdcall;
  92.     function get_BitErrorRate(out pBitErrorRate: Longint): HResult; stdcall;
  93.     function get_VideoWidth(out pVideoWidth: Longint): HResult; stdcall;
  94.     function get_VideoHeight(out pVideoHeight: Longint): HResult; stdcall;
  95.     function put_SourceLeft(SourceLeft: Longint): HResult; stdcall;
  96.     function get_SourceLeft(out pSourceLeft: Longint): HResult; stdcall;
  97.     function put_SourceWidth(SourceWidth: Longint): HResult; stdcall;
  98.     function get_SourceWidth(out pSourceWidth: Longint): HResult; stdcall;
  99.     function put_SourceTop(SourceTop: Longint): HResult; stdcall;
  100.     function get_SourceTop(out pSourceTop: Longint): HResult; stdcall;
  101.     function put_SourceHeight(SourceHeight: Longint): HResult; stdcall;
  102.     function get_SourceHeight(out pSourceHeight: Longint): HResult; stdcall;
  103.     function put_DestinationLeft(DestinationLeft: Longint): HResult; stdcall;
  104.     function get_DestinationLeft(out pDestinationLeft: Longint): HResult; stdcall;
  105.     function put_DestinationWidth(DestinationWidth: Longint): HResult; stdcall;
  106.     function get_DestinationWidth(out pDestinationWidth: Longint): HResult; stdcall;
  107.     function put_DestinationTop(DestinationTop: Longint): HResult; stdcall;
  108.     function get_DestinationTop(out pDestinationTop: Longint): HResult; stdcall;
  109.     function put_DestinationHeight(DestinationHeight: Longint): HResult; stdcall;
  110.     function get_DestinationHeight(out pDestinationHeight: Longint): HResult; stdcall;
  111.     function SetSourcePosition(Left, Top, Width, Height: Longint): HResult; stdcall;
  112.     function GetSourcePosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  113.     function SetDefaultSourcePosition: HResult; stdcall;
  114.     function SetDestinationPosition(Left, Top, Width, Height: Longint): HResult; stdcall;
  115.     function GetDestinationPosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  116.     function SetDefaultDestinationPosition: HResult; stdcall;
  117.     function GetVideoSize(out pWidth, Height: Longint): HResult; stdcall;
  118.     function GetVideoPaletteEntries(StartIndex, Entries: Longint; out pRetrieved: Longint; out pPalette): HResult; stdcall;
  119.     function GetCurrentImage(var BufferSize: Longint; var pDIBImage): HResult; stdcall;
  120.     function IsUsingDefaultSource: HResult; stdcall;
  121.     function IsUsingDefaultDestination: HResult; stdcall;
  122.     (*** IBasicVideo2 methods ***)
  123.     function GetPreferredAspectRatio(out plAspectX, plAspectY: Longint): HResult; stdcall;
  124.     (*** IAMFilterMiscFlags methods ***)
  125.     function GetMiscFlags: ULONG; stdcall;
  126.   end;
  127. implementation
  128. function CheckConnected(Pin : TBCBasePin; out Res : HRESULT) : Boolean;
  129. begin
  130.   if not Pin.IsConnected then
  131.   begin
  132.     Res := VFW_E_NOT_CONNECTED;
  133.     Result := False;
  134.   end else
  135.   begin
  136.     Res := S_OK;
  137.     Result := True;
  138.   end;
  139. end;
  140. constructor TVideoRenderer.Create(ObjName: String; Unk: IUnknown; out hr: HResult);
  141. begin
  142.   inherited Create(CLSID_DelphiVideoRenderer, 'Delphi Video Renderer', Unk, hr);
  143.   fDispatch := TBCBaseDispatch.Create;
  144.   fRenderer := TfrmRenderer.Create(nil);
  145.   fAutoShow := True;
  146. end;
  147. constructor TVideoRenderer.CreateFromFactory(Factory: TBCClassFactory; const Controller: IUnknown);
  148. var
  149.   hr: HRESULT;
  150. begin
  151.   Create(Factory.Name, Controller, hr);
  152. end;
  153. destructor TVideoRenderer.Destroy;
  154. begin
  155.   if Assigned(fDispatch) then FreeAndNil(fDispatch);
  156.   if Assigned(fRenderer) then FreeAndNil(fRenderer);
  157.   inherited Destroy;
  158. end;
  159. function TVideoRenderer.Active: HResult;
  160. begin
  161.   if fAutoShow then fRenderer.Show;
  162.   Result := inherited Active;
  163. end;
  164. function TVideoRenderer.Inactive: HResult;
  165. begin
  166.   Result := inherited Inactive;
  167. end;
  168. function TVideoRenderer.CheckMediaType(MediaType: PAMMediaType): HResult;
  169. begin
  170.   if (MediaType = nil) then
  171.   begin
  172.     Result := E_POINTER;
  173.     Exit;
  174.   end;
  175.   if not IsEqualGUID(MediaType.majortype, MEDIATYPE_Video) or
  176.      not IsEqualGUID(MediaType.subtype, MEDIASUBTYPE_RGB24) or
  177.      not IsEqualGUID(MediaType.formattype, FORMAT_VideoInfo) then
  178.   begin
  179.     Result := E_INVALIDARG;
  180.     Exit;
  181.   end;
  182.   Result := NOERROR;
  183. end;
  184. function TVideoRenderer.DoRenderSample(MediaSample: IMediaSample): HResult;
  185. begin
  186.   if (MediaSample = nil) then
  187.   begin
  188.     Result := E_POINTER;
  189.     Exit;
  190.   end;
  191.   fRenderer.DoRenderSample(MediaSample);
  192.   Result := NOERROR;
  193. end;
  194. procedure TVideoRenderer.OnReceiveFirstSample(MediaSample: IMediaSample);
  195. begin
  196.   DoRenderSample(MediaSample);
  197. end;
  198. function TVideoRenderer.SetMediaType(MediaType: PAMMediaType): HResult;
  199. var
  200.   VIH: PVIDEOINFOHEADER;
  201. begin
  202.   if (MediaType = nil) then
  203.   begin
  204.     Result := E_POINTER;
  205.     Exit;
  206.   end;
  207.   VIH := PVIDEOINFOHEADER(MediaType.pbFormat);
  208.   if (VIH = nil) then
  209.   begin
  210.     Result := E_UNEXPECTED;
  211.     Exit;
  212.   end;
  213.   CopyMemory(@fFormat,VIH,SizeOf(TVideoInfoHeader));
  214.   fRenderer.DoInitializeDirectDraw(@fFormat);
  215.   Result := S_OK;
  216. end;
  217. {*** IDispatch methods *** taken from CBaseVideoWindow *** ctlutil.cpp ********}
  218. function TVideoRenderer.GetTypeInfoCount(out Count: Integer): HResult; stdcall;
  219. begin
  220.   Result := fDispatch.GetTypeInfoCount(Count);
  221. end;
  222. function TVideoRenderer.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
  223. begin
  224.   Result := fDispatch.GetTypeInfo(IID_IVideoWindow,Index,LocaleID,TypeInfo);
  225. end;
  226. function TVideoRenderer.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
  227. begin
  228.   Result := fDispatch.GetIDsOfNames(IID_IVideoWindow,Names,NameCount,LocaleID,DispIDs);
  229. end;
  230. function TVideoRenderer.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
  231. var
  232.   pti : ITypeInfo;
  233. begin
  234.   if not IsEqualGUID(GUID_NULL,IID) then
  235.   begin
  236.     Result := DISP_E_UNKNOWNINTERFACE;
  237.     Exit;
  238.   end;
  239.   Result := GetTypeInfo(0, LocaleID, pti);
  240.   if FAILED(Result) then Exit;
  241.   Result :=  pti.Invoke(Pointer(Self as IVideoWindow),DispID,Flags,
  242.                         TDispParams(Params),VarResult,ExcepInfo,ArgErr);
  243.   pti := nil;
  244. end;
  245. (*** IVideoWindow methods *****************************************************)
  246. function TVideoRenderer.put_Caption(strCaption: WideString): HResult; stdcall;
  247. begin
  248.   if not CheckConnected(FInputPin,Result) then Exit;
  249.   fRenderer.Caption := strCaption;
  250. end;
  251. function TVideoRenderer.get_Caption(out strCaption: WideString): HResult; stdcall;
  252. begin
  253.   if not CheckConnected(FInputPin,Result) then Exit;
  254.   strCaption := fRenderer.Caption;
  255. end;
  256. function TVideoRenderer.put_WindowStyle(WindowStyle: Longint): HResult; stdcall;
  257. begin
  258.   if not CheckConnected(FInputPin,Result) then Exit;
  259.   // These styles cannot be changed dynamically
  260.   if (Bool(WindowStyle and WS_DISABLED) or
  261.       Bool(WindowStyle and WS_ICONIC) or
  262.       Bool(WindowStyle and WS_MAXIMIZE) or
  263.       Bool(WindowStyle and WS_MINIMIZE) or
  264.       Bool(WindowStyle and WS_HSCROLL) or
  265.       Bool(WindowStyle and WS_VSCROLL)) then
  266.       begin
  267.         Result := E_INVALIDARG;
  268.         Exit;
  269.       end;
  270.       
  271.   Result := fRenderer.DoSetWindowStyle(WindowStyle,GWL_STYLE);
  272. end;
  273. function TVideoRenderer.get_WindowStyle(out WindowStyle: Longint): HResult; stdcall;
  274. begin
  275.   if not CheckConnected(FInputPin,Result) then Exit;
  276.   Result := fRenderer.DoGetWindowStyle(WindowStyle,GWL_STYLE);
  277. end;
  278. function TVideoRenderer.put_WindowStyleEx(WindowStyleEx: Longint): HResult; stdcall;
  279. begin
  280.   if not CheckConnected(FInputPin,Result) then Exit;
  281.   // Should we be taking off WS_EX_TOPMOST
  282.   if (GetWindowLong(fRenderer.Handle,GWL_EXSTYLE) and WS_EX_TOPMOST > 0) then
  283.   begin
  284.     if ((WindowStyleEx and WS_EX_TOPMOST) = 0) then
  285.     begin
  286. //      SendMessage(fRenderer.Handle,m_ShowStageTop,WPARAM(FALSE),0);
  287.     end;
  288.   end;
  289.   // Likewise should we be adding WS_EX_TOPMOST
  290.   if (WindowStyleEx and WS_EX_TOPMOST > 0) then
  291.   begin
  292. //    SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) TRUE,(LPARAM) 0);
  293.     WindowStyleEx := WindowStyleEx and not WS_EX_TOPMOST;
  294.     if (WindowStyleEx = 0) then
  295.     begin
  296.       Result := NOERROR;
  297.       Exit;
  298.     end;
  299.   end;
  300.   Result := fRenderer.DoSetWindowStyle(WindowStyleEx,GWL_EXSTYLE);
  301. end;
  302. function TVideoRenderer.get_WindowStyleEx(out WindowStyleEx: Longint): HResult; stdcall;
  303. begin
  304.   if not CheckConnected(FInputPin,Result) then Exit;
  305.   Result := fRenderer.DoGetWindowStyle(WindowStyleEx,GWL_EXSTYLE);
  306. end;
  307. function TVideoRenderer.put_AutoShow(AutoShow: LongBool): HResult; stdcall;
  308. begin
  309.   if not CheckConnected(FInputPin,Result) then Exit;
  310.   fAutoShow := AutoShow;
  311. end;
  312. function TVideoRenderer.get_AutoShow(out AutoShow: LongBool): HResult; stdcall;
  313. begin
  314.   if not CheckConnected(FInputPin,Result) then Exit;
  315.   AutoShow := fAutoShow;
  316. end;
  317. function TVideoRenderer.put_WindowState(WindowState: Longint): HResult; stdcall;
  318. begin
  319.   if not CheckConnected(FInputPin,Result) then Exit;
  320.   Result := fRenderer.DoShowWindow(WindowState);
  321. end;
  322. function TVideoRenderer.get_WindowState(out WindowState: Longint): HResult; stdcall;
  323. begin
  324.   if not CheckConnected(FInputPin,Result) then Exit;
  325.   WindowState := 0;
  326.   // Is the window visible, a window is termed visible if it is somewhere on
  327.   // the current desktop even if it is completely obscured by other windows
  328.   // so the flag is a style for each window set with the WS_VISIBLE bit
  329.   if fRenderer.Visible then
  330.   begin
  331.     // Is the base window iconic
  332.     if IsIconic(fRenderer.Handle) then
  333.     begin
  334.       WindowState := WindowState or SW_MINIMIZE;
  335.     end
  336.     // Has the window been maximised
  337.     else if IsZoomed(fRenderer.Handle) then
  338.     begin
  339.       WindowState := WindowState or SW_MAXIMIZE;
  340.     end
  341.     // Window is normal
  342.     else
  343.     begin
  344.       WindowState := WindowState or SW_SHOW;
  345.     end
  346.   end else
  347.   begin
  348.     WindowState := WindowState or SW_HIDE;
  349.   end;
  350.   Result := NOERROR;
  351. end;
  352. function TVideoRenderer.put_BackgroundPalette(BackgroundPalette: Longint): HResult; stdcall;
  353. begin
  354.   if not CheckConnected(FInputPin,Result) then Exit;
  355.   Result := E_NOTIMPL;
  356. end;
  357. function TVideoRenderer.get_BackgroundPalette(out pBackgroundPalette: Longint): HResult; stdcall;
  358. begin
  359.   if not CheckConnected(FInputPin,Result) then Exit;
  360.   Result := E_NOTIMPL;
  361. end;
  362. function TVideoRenderer.put_Visible(Visible: LongBool): HResult; stdcall;
  363. begin
  364.   if not CheckConnected(FInputPin,Result) then Exit;
  365.   fRenderer.Visible := Visible;
  366. end;
  367. function TVideoRenderer.get_Visible(out pVisible: LongBool): HResult; stdcall;
  368. begin
  369.   if not CheckConnected(FInputPin,Result) then Exit;
  370.   pVisible := fRenderer.Visible;
  371. end;
  372. function TVideoRenderer.put_Left(Left: Longint): HResult; stdcall;
  373. var
  374.   bSuccess : Boolean;
  375.   WindowRect : TRect;
  376.   WindowFlags : Cardinal;
  377. begin
  378.   if not CheckConnected(FInputPin,Result) then Exit;
  379.   // Get the current window position in a RECT
  380.   GetWindowRect(fRenderer.Handle,WindowRect);
  381.   if (fRenderer.ParentWindow > 0) then
  382.     MapWindowPoints(HWND_DESKTOP, fRenderer.ParentWindow, WindowRect, 2);
  383.   // Adjust the coordinates ready for SetWindowPos, the window rectangle we
  384.   // get back from GetWindowRect is in left,top,right and bottom while the
  385.   // coordinates SetWindowPos wants are left,top,width and height values
  386.   WindowRect.bottom := WindowRect.bottom - WindowRect.top;
  387.   WindowRect.right := WindowRect.right - WindowRect.left;
  388.   WindowFlags := SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE;
  389.   bSuccess := SetWindowPos(fRenderer.Handle,                // Window handle
  390.                            HWND_TOP,              // Put it at the top
  391.                            Left,                  // New left position
  392.                            WindowRect.top,        // Leave top alone
  393.                            WindowRect.right,      // The WIDTH (not right)
  394.                            WindowRect.bottom,     // The HEIGHT (not bottom)
  395.                            WindowFlags);          // Show window options
  396.   if not bSuccess then Result := E_INVALIDARG
  397.                   else Result := NOERROR;
  398. end;
  399. function TVideoRenderer.get_Left(out pLeft: Longint): HResult; stdcall;
  400. var
  401.   WindowRect : TRect;
  402. begin
  403.   if not CheckConnected(FInputPin,Result) then Exit;
  404.   GetWindowRect(fRenderer.Handle,WindowRect);
  405.   pLeft := WindowRect.left;
  406.   Result := S_OK;
  407. end;
  408. function TVideoRenderer.put_Width(Width: Longint): HResult; stdcall;
  409. var
  410.   bSuccess : Boolean;
  411.   WindowRect : TRect;
  412.   WindowFlags : Cardinal;
  413. begin
  414.   if not CheckConnected(FInputPin,Result) then Exit;
  415.   // Adjust the coordinates ready for SetWindowPos, the window rectangle we
  416.   // get back from GetWindowRect is in left,top,right and bottom while the
  417.   // coordinates SetWindowPos wants are left,top,width and height values
  418.   GetWindowRect(fRenderer.Handle,WindowRect);
  419.   if (fRenderer.ParentWindow > 0)
  420.     then MapWindowPoints(HWND_DESKTOP, fRenderer.ParentWindow, WindowRect, 2);
  421.   WindowRect.bottom := WindowRect.bottom - WindowRect.top;
  422.   WindowFlags := SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE;
  423.     // This seems to have a bug in that calling SetWindowPos on a window with
  424.     // just the width changing causes it to ignore the width that you pass in
  425.     // and sets it to a mimimum value of 110 pixels wide (Windows NT 3.51)
  426.   bSuccess := SetWindowPos(fRenderer.Handle,                // Window handle
  427.                            HWND_TOP,              // Put it at the top
  428.                            WindowRect.left,       // Leave left alone
  429.                            WindowRect.top,        // Leave top alone
  430.                            Width,                 // New WIDTH dimension
  431.                            WindowRect.bottom,     // The HEIGHT (not bottom)
  432.                            WindowFlags);          // Show window options
  433.   if not bSuccess then Result := E_INVALIDARG
  434.                   else Result := NOERROR;
  435. end;
  436. function TVideoRenderer.get_Width(out pWidth: Longint): HResult; stdcall;
  437. var
  438.   WindowRect : TRect;
  439. begin
  440.   if not CheckConnected(FInputPin,Result) then Exit;
  441.   GetWindowRect(fRenderer.Handle,WindowRect);
  442.   pWidth := WindowRect.right - WindowRect.left;
  443.   Result := NOERROR;
  444. end;
  445. function TVideoRenderer.put_Top(Top: Longint): HResult; stdcall;
  446. var
  447.   bSuccess : Boolean;
  448.   WindowRect : TRect;
  449.   WindowFlags : Cardinal;
  450. begin
  451.   if not CheckConnected(FInputPin,Result) then Exit;
  452.   // Get the current window position in a RECT
  453.   GetWindowRect(fRenderer.Handle,WindowRect);
  454.   if (fRenderer.ParentWindow > 0) then
  455.      MapWindowPoints(HWND_DESKTOP, fRenderer.ParentWindow, WindowRect, 2);
  456.   // Adjust the coordinates ready for SetWindowPos, the window rectangle we
  457.   // get back from GetWindowRect is in left,top,right and bottom while the
  458.   // coordinates SetWindowPos wants are left,top,width and height values
  459.   WindowRect.bottom := WindowRect.bottom - WindowRect.top;
  460.   WindowRect.right := WindowRect.right - WindowRect.left;
  461.   WindowFlags := SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE;
  462.   bSuccess := SetWindowPos(fRenderer.Handle,                // Window handle
  463.                            HWND_TOP,              // Put it at the top
  464.                            WindowRect.left,       // Leave left alone
  465.                            Top,                   // New top position
  466.                            WindowRect.right,      // The WIDTH (not right)
  467.                            WindowRect.bottom,     // The HEIGHT (not bottom)
  468.                            WindowFlags);          // Show window flags
  469.   if not bSuccess then Result := E_INVALIDARG
  470.                   else Result := NOERROR;
  471. end;
  472. function TVideoRenderer.get_Top(out pTop: Longint): HResult; stdcall;
  473. var
  474.   WindowRect : TRect;
  475. begin
  476.   if not CheckConnected(FInputPin,Result) then Exit;
  477.   GetWindowRect(fRenderer.Handle,WindowRect);
  478.   pTop := WindowRect.Top;
  479.   Result := NOERROR;
  480. end;
  481. function TVideoRenderer.put_Height(Height: Longint): HResult; stdcall;
  482. var
  483.   bSuccess : Boolean;
  484.   WindowRect : TRect;
  485.   WindowFlags : Cardinal;
  486. begin
  487.   if not CheckConnected(FInputPin,Result) then Exit;
  488.   // Adjust the coordinates ready for SetWindowPos, the window rectangle we
  489.   // get back from GetWindowRect is in left,top,right and bottom while the
  490.   // coordinates SetWindowPos wants are left,top,width and height values
  491.   GetWindowRect(fRenderer.Handle,WindowRect);
  492.   if (fRenderer.ParentWindow > 0) then
  493.      MapWindowPoints(HWND_DESKTOP, fRenderer.ParentWindow, WindowRect, 2);
  494.   WindowRect.right := WindowRect.right - WindowRect.left;
  495.   WindowFlags := SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE;
  496.   bSuccess := SetWindowPos(fRenderer.Handle,                // Window handle
  497.                            HWND_TOP,              // Put it at the top
  498.                            WindowRect.left,       // Leave left alone
  499.                            WindowRect.top,        // Leave top alone
  500.                            WindowRect.right,      // The WIDTH (not right)
  501.                            Height,                // New height dimension
  502.                            WindowFlags);          // Show window flags
  503.   if not bSuccess then Result := E_INVALIDARG
  504.                   else Result := NOERROR;
  505. end;
  506. function TVideoRenderer.get_Height(out pHeight: Longint): HResult; stdcall;
  507. var
  508.   WindowRect : TRect;
  509. begin
  510.   if not CheckConnected(FInputPin,Result) then Exit;
  511.   GetWindowRect(fRenderer.Handle,WindowRect);
  512.   pHeight := WindowRect.bottom - WindowRect.top;
  513.   Result := NOERROR;
  514. end;
  515. function TVideoRenderer.put_Owner(Owner: OAHWND): HResult; stdcall;
  516. begin
  517.   if not CheckConnected(FInputPin,Result) then Exit;
  518.   fRenderer.ParentWindow := Owner;
  519.   // Don't call this with the filter locked
  520.   fRenderer.DoPaintWindow(True);
  521.   {$IFDEF DEBUG}
  522.   DbgLog(Self,'Changed parent to $' + inttohex(hwndParent,8));
  523.   {$ENDIF}
  524.   Result := NOERROR;
  525. end;
  526. function TVideoRenderer.get_Owner(out Owner: OAHWND): HResult; stdcall;
  527. begin
  528.   if not CheckConnected(FInputPin,Result) then Exit;
  529.   Owner := fRenderer.ParentWindow;
  530. end;
  531. function TVideoRenderer.put_MessageDrain(Drain: OAHWND): HResult; stdcall;
  532. begin
  533.   if not CheckConnected(FInputPin,Result) then Exit;
  534.   fRenderer.MessageDrain := Drain;
  535. end;
  536. function TVideoRenderer.get_MessageDrain(out Drain: OAHWND): HResult; stdcall;
  537. begin
  538.   if not CheckConnected(FInputPin,Result) then Exit;
  539.   Drain := fRenderer.MessageDrain;
  540. end;
  541. function TVideoRenderer.get_BorderColor(out Color: Longint): HResult; stdcall;
  542. begin
  543.   if not CheckConnected(FInputPin,Result) then Exit;
  544.   Result := E_NOTIMPL;
  545. end;
  546. function TVideoRenderer.put_BorderColor(Color: Longint): HResult; stdcall;
  547. begin
  548.   if not CheckConnected(FInputPin,Result) then Exit;
  549.   Result := E_NOTIMPL;
  550. end;
  551. function TVideoRenderer.get_FullScreenMode(out FullScreenMode: LongBool): HResult; stdcall;
  552. begin
  553.   if not CheckConnected(FInputPin,Result) then Exit;
  554.   Result := E_NOTIMPL;
  555. end;
  556. function TVideoRenderer.put_FullScreenMode(FullScreenMode: LongBool): HResult; stdcall;
  557. begin
  558.   if not CheckConnected(FInputPin,Result) then Exit;
  559.   Result := E_NOTIMPL;
  560. end;
  561. function TVideoRenderer.SetWindowForeground(Focus: Longint): HResult; stdcall;
  562. begin
  563.   if not CheckConnected(FInputPin,Result) then Exit;
  564.   SendMessage(fRenderer.Handle,WM_SHOWWINDOW,Focus,0);
  565. end;
  566. function TVideoRenderer.NotifyOwnerMessage(hwnd: Longint; uMsg, wParam, lParam: Longint): HResult; stdcall;
  567. begin
  568.   if not CheckConnected(FInputPin,Result) then Exit;
  569.   // Only interested in these Windows messages
  570.   case uMsg of
  571.     WM_SYSCOLORCHANGE,
  572.     WM_PALETTECHANGED,
  573.     WM_PALETTEISCHANGING,
  574.     WM_QUERYNEWPALETTE,
  575.     WM_DEVMODECHANGE,
  576.     WM_DISPLAYCHANGE,
  577.     WM_ACTIVATEAPP:
  578.     begin
  579.       // If we do not have an owner then ignore
  580.       if (fRenderer.ParentWindow = 0) then
  581.       begin
  582.         Result := NOERROR;
  583.         Exit;
  584.       end;
  585.       SendMessage(fRenderer.Handle,uMsg,wParam,lParam);
  586.     end;
  587.     // do NOT fwd WM_MOVE. the parameters are the location of the parent
  588.     // window, NOT what the renderer should be looking at.  But we need
  589.     // to make sure the overlay is moved with the parent window, so we
  590.     // do this.
  591.     WM_MOVE: PostMessage(fRenderer.Handle,WM_PAINT,0,0);
  592.   end;
  593. end;
  594. function TVideoRenderer.SetWindowPosition(Left, Top, Width, Height: Longint): HResult; stdcall;
  595. var
  596.   bSuccess : Boolean;
  597.   WindowFlags : Cardinal;
  598. begin
  599.   if not CheckConnected(FInputPin,Result) then Exit;
  600.   // Set the new size and position
  601.   WindowFlags := SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE;
  602.   ASSERT(IsWindow(fRenderer.Handle));
  603.   bSuccess := SetWindowPos(fRenderer.Handle,         // Window handle
  604.                            HWND_TOP,       // Put it at the top
  605.                            Left,           // Left position
  606.                            Top,            // Top position
  607.                            Width,          // Window width
  608.                            Height,         // Window height
  609.                            WindowFlags);   // Show window flags
  610.   ASSERT(bSuccess);
  611.   {$IFDEF DEBUG}
  612.     DbgLog(Self,'SWP failed error : ' + inttohex(GetLastError,8));
  613.   {$ENDIF}
  614.   if not bSuccess then Result := E_INVALIDARG
  615.                   else Result := NOERROR;
  616. end;
  617. function TVideoRenderer.GetWindowPosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  618. var
  619.   WindowRect : TRect;
  620. begin
  621.   if not CheckConnected(FInputPin,Result) then Exit;
  622.   // Get the current window coordinates
  623.   GetWindowRect(fRenderer.Handle,WindowRect);
  624.   // Convert the RECT into left,top,width and height values
  625.   pLeft := WindowRect.left;
  626.   pTop := WindowRect.top;
  627.   pWidth := WindowRect.right - WindowRect.left;
  628.   pHeight := WindowRect.bottom - WindowRect.top;
  629.   Result := NOERROR;
  630. end;
  631. function TVideoRenderer.GetMinIdealImageSize(out pWidth, pHeight: Longint): HResult; stdcall;
  632. var
  633.   State : TFilterState;
  634.   DefaultRect : TRect;
  635. begin
  636.   if not CheckConnected(FInputPin,Result) then Exit;
  637.   // Must not be stopped for this to work correctly
  638.   GetState(0,State);
  639.   if (State = State_Stopped) then
  640.   begin
  641.     Result := VFW_E_WRONG_STATE;
  642.     Exit;
  643.   end;
  644.   DefaultRect := Rect(0,0,DEFWIDTH,DEFHEIGHT);
  645.   pWidth := DefaultRect.Right - DefaultRect.Left;
  646.   pHeight := DefaultRect.Bottom - DefaultRect.Top;
  647.   Result := NOERROR;
  648. end;
  649. function TVideoRenderer.GetMaxIdealImageSize(out pWidth, pHeight: Longint): HResult; stdcall;
  650. var
  651.   State : TFilterState;
  652.   DefaultRect : TRect;
  653. begin
  654.   if not CheckConnected(FInputPin,Result) then Exit;
  655.   // Must not be stopped for this to work correctly
  656.   GetState(0,State);
  657.   if (State = State_Stopped) then
  658.   begin
  659.     Result := VFW_E_WRONG_STATE;
  660.     Exit;
  661.   end;
  662.   DefaultRect := Rect(0,0,DEFWIDTH,DEFHEIGHT);
  663.   pWidth := DefaultRect.Right - DefaultRect.Left;
  664.   pHeight := DefaultRect.Bottom - DefaultRect.Top;
  665.   Result := NOERROR;
  666. end;
  667. function TVideoRenderer.GetRestorePosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  668. var
  669.   Place : TWindowPlacement;
  670.   WorkArea : TRect;
  671. begin
  672.   if not CheckConnected(FInputPin,Result) then Exit;
  673.   // Use GetWindowPlacement to find the restore position
  674.   Place.length := sizeof(TWindowPlacement);
  675.   GetWindowPlacement(fRenderer.Handle,@Place);
  676.   // We must take into account any task bar present
  677.   if SystemParametersInfo(SPI_GETWORKAREA,0,@WorkArea,0) then
  678.   begin
  679.     if (fRenderer.ParentWindow = 0) then
  680.     begin
  681.       inc(Place.rcNormalPosition.top,WorkArea.top);
  682.       inc(Place.rcNormalPosition.bottom,WorkArea.top);
  683.       inc(Place.rcNormalPosition.left,WorkArea.left);
  684.       inc(Place.rcNormalPosition.right,WorkArea.left);
  685.     end;
  686.   end;
  687.   // Convert the RECT into left,top,width and height values
  688.   pLeft := Place.rcNormalPosition.left;
  689.   pTop := Place.rcNormalPosition.top;
  690.   pWidth := Place.rcNormalPosition.right - Place.rcNormalPosition.left;
  691.   pHeight := Place.rcNormalPosition.bottom - Place.rcNormalPosition.top;
  692.   Result := NOERROR;
  693. end;
  694. function TVideoRenderer.HideCursor(HideCursor: LongBool): HResult; stdcall;
  695. begin
  696.   if not CheckConnected(FInputPin,Result) then Exit;
  697.   Result := E_NOTIMPL;
  698. end;
  699. function TVideoRenderer.IsCursorHidden(out CursorHidden: LongBool): HResult; stdcall;
  700. begin
  701.   if not CheckConnected(FInputPin,Result) then Exit;
  702.   Result := E_NOTIMPL;
  703. end;
  704. (*** IBasicVideo methods ******************************************************)
  705. function TVideoRenderer.get_AvgTimePerFrame(out pAvgTimePerFrame: TRefTime): HResult; stdcall;
  706. begin
  707.   if not CheckConnected(FInputPin,Result) then Exit;
  708.   pAvgTimePerFrame := fFormat.AvgTimePerFrame;
  709.   Result := NOERROR;
  710. end;
  711. function TVideoRenderer.get_BitRate(out pBitRate: Longint): HResult; stdcall;
  712. begin
  713.   if not CheckConnected(FInputPin,Result) then Exit;
  714.   pBitRate := fFormat.dwBitRate;
  715.   Result := NOERROR;
  716. end;
  717. function TVideoRenderer.get_BitErrorRate(out pBitErrorRate: Longint): HResult; stdcall;
  718. begin
  719.   if not CheckConnected(FInputPin,Result) then Exit;
  720.   pBitErrorRate := fFormat.dwBitErrorRate;
  721.   Result := NOERROR;
  722. end;
  723. function TVideoRenderer.get_VideoWidth(out pVideoWidth: Longint): HResult; stdcall;
  724. begin
  725.   if not CheckConnected(FInputPin,Result) then Exit;
  726.   pVideoWidth := fFormat.bmiHeader.biWidth;
  727.   Result := NOERROR;
  728. end;
  729. function TVideoRenderer.get_VideoHeight(out pVideoHeight: Longint): HResult; stdcall;
  730. begin
  731.   if not CheckConnected(FInputPin,Result) then Exit;
  732.   pVideoHeight := fFormat.bmiHeader.biHeight;
  733.   Result := NOERROR;
  734. end;
  735. function TVideoRenderer.put_SourceLeft(SourceLeft: Longint): HResult; stdcall;
  736. begin
  737.   if not CheckConnected(FInputPin,Result) then Exit;
  738.   Result := E_NOTIMPL;
  739. end;
  740. function TVideoRenderer.get_SourceLeft(out pSourceLeft: Longint): HResult; stdcall;
  741. begin
  742.   if not CheckConnected(FInputPin,Result) then Exit;
  743.   Result := E_NOTIMPL;
  744. end;
  745. function TVideoRenderer.put_SourceWidth(SourceWidth: Longint): HResult; stdcall;
  746. begin
  747.   if not CheckConnected(FInputPin,Result) then Exit;
  748.   Result := E_NOTIMPL;
  749. end;
  750. function TVideoRenderer.get_SourceWidth(out pSourceWidth: Longint): HResult; stdcall;
  751. begin
  752.   if not CheckConnected(FInputPin,Result) then Exit;
  753.   Result := E_NOTIMPL;
  754. end;
  755. function TVideoRenderer.put_SourceTop(SourceTop: Longint): HResult; stdcall;
  756. begin
  757.   if not CheckConnected(FInputPin,Result) then Exit;
  758.   Result := E_NOTIMPL;
  759. end;
  760. function TVideoRenderer.get_SourceTop(out pSourceTop: Longint): HResult; stdcall;
  761. begin
  762.   if not CheckConnected(FInputPin,Result) then Exit;
  763.   Result := E_NOTIMPL;
  764. end;
  765. function TVideoRenderer.put_SourceHeight(SourceHeight: Longint): HResult; stdcall;
  766. begin
  767.   if not CheckConnected(FInputPin,Result) then Exit;
  768.   Result := E_NOTIMPL;
  769. end;
  770. function TVideoRenderer.get_SourceHeight(out pSourceHeight: Longint): HResult; stdcall;
  771. begin
  772.   if not CheckConnected(FInputPin,Result) then Exit;
  773.   Result := E_NOTIMPL;
  774. end;
  775. function TVideoRenderer.put_DestinationLeft(DestinationLeft: Longint): HResult; stdcall;
  776. begin
  777.   if not CheckConnected(FInputPin,Result) then Exit;
  778.   Result := E_NOTIMPL;
  779. end;
  780. function TVideoRenderer.get_DestinationLeft(out pDestinationLeft: Longint): HResult; stdcall;
  781. begin
  782.   if not CheckConnected(FInputPin,Result) then Exit;
  783.   Result := E_NOTIMPL;
  784. end;
  785. function TVideoRenderer.put_DestinationWidth(DestinationWidth: Longint): HResult; stdcall;
  786. begin
  787.   if not CheckConnected(FInputPin,Result) then Exit;
  788.   Result := E_NOTIMPL;
  789. end;
  790. function TVideoRenderer.get_DestinationWidth(out pDestinationWidth: Longint): HResult; stdcall;
  791. begin
  792.   if not CheckConnected(FInputPin,Result) then Exit;
  793.   Result := E_NOTIMPL;
  794. end;
  795. function TVideoRenderer.put_DestinationTop(DestinationTop: Longint): HResult; stdcall;
  796. begin
  797.   if not CheckConnected(FInputPin,Result) then Exit;
  798.   Result := E_NOTIMPL;
  799. end;
  800. function TVideoRenderer.get_DestinationTop(out pDestinationTop: Longint): HResult; stdcall;
  801. begin
  802.   if not CheckConnected(FInputPin,Result) then Exit;
  803.   Result := E_NOTIMPL;
  804. end;
  805. function TVideoRenderer.put_DestinationHeight(DestinationHeight: Longint): HResult; stdcall;
  806. begin
  807.   if not CheckConnected(FInputPin,Result) then Exit;
  808.   Result := E_NOTIMPL;
  809. end;
  810. function TVideoRenderer.get_DestinationHeight(out pDestinationHeight: Longint): HResult; stdcall;
  811. begin
  812.   if not CheckConnected(FInputPin,Result) then Exit;
  813.   Result := E_NOTIMPL;
  814. end;
  815. function TVideoRenderer.SetSourcePosition(Left, Top, Width, Height: Longint): HResult; stdcall;
  816. begin
  817.   if not CheckConnected(FInputPin,Result) then Exit;
  818.   Result := E_NOTIMPL;
  819. end;
  820. function TVideoRenderer.GetSourcePosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  821. begin
  822.   if not CheckConnected(FInputPin,Result) then Exit;
  823.   Result := E_NOTIMPL;
  824. end;
  825. function TVideoRenderer.SetDefaultSourcePosition: HResult; stdcall;
  826. begin
  827.   if not CheckConnected(FInputPin,Result) then Exit;
  828.   Result := E_NOTIMPL;
  829. end;
  830. function TVideoRenderer.SetDestinationPosition(Left, Top, Width, Height: Longint): HResult; stdcall;
  831. begin
  832.   if not CheckConnected(FInputPin,Result) then Exit;
  833.   Result := E_NOTIMPL;
  834. end;
  835. function TVideoRenderer.GetDestinationPosition(out pLeft, pTop, pWidth, pHeight: Longint): HResult; stdcall;
  836. begin
  837.   if not CheckConnected(FInputPin,Result) then Exit;
  838.   Result := E_NOTIMPL;
  839. end;
  840. function TVideoRenderer.SetDefaultDestinationPosition: HResult; stdcall;
  841. begin
  842.   if not CheckConnected(FInputPin,Result) then Exit;
  843.   Result := E_NOTIMPL;
  844. end;
  845. function TVideoRenderer.GetVideoSize(out pWidth, Height: Longint): HResult; stdcall;
  846. begin
  847.   if not CheckConnected(FInputPin,Result) then Exit;
  848.   pWidth := fFormat.bmiHeader.biWidth;
  849.   Height := fFormat.bmiHeader.biHeight;
  850.   Result := NOERROR;
  851. end;
  852. function TVideoRenderer.GetVideoPaletteEntries(StartIndex, Entries: Longint; out pRetrieved: Longint; out pPalette): HResult; stdcall;
  853. begin
  854.   if not CheckConnected(FInputPin,Result) then Exit;
  855.   Result := E_NOTIMPL;
  856. end;
  857. function TVideoRenderer.GetCurrentImage(var BufferSize: Longint; var pDIBImage): HResult; stdcall;
  858. begin
  859.   if not CheckConnected(FInputPin,Result) then Exit;
  860.   Result := E_NOTIMPL;
  861. end;
  862. function TVideoRenderer.IsUsingDefaultSource: HResult; stdcall;
  863. begin
  864.   if not CheckConnected(FInputPin,Result) then Exit;
  865.   Result := E_NOTIMPL;
  866. end;
  867. function TVideoRenderer.IsUsingDefaultDestination: HResult; stdcall;
  868. begin
  869.   if not CheckConnected(FInputPin,Result) then Exit;
  870.   Result := E_NOTIMPL;
  871. end;
  872. (*** IBasicVideo2 methods *****************************************************)
  873. function TVideoRenderer.GetPreferredAspectRatio(out plAspectX, plAspectY: Longint): HResult; stdcall;
  874. begin
  875.   if not CheckConnected(FInputPin,Result) then Exit;
  876.   Result := E_NOTIMPL;
  877. end;
  878. (*** IAMFilterMiscFlags methods ***********************************************)
  879. function TVideoRenderer.GetMiscFlags: ULONG; stdcall;
  880. begin
  881.   Result := AM_FILTER_MISC_FLAGS_IS_RENDERER;
  882. end;
  883. (******************************************************************************)
  884. initialization
  885.   TBCClassFactory.CreateFilter(TVideoRenderer, '_Delphi Video Renderer',
  886.     CLSID_VideoRenderer, CLSID_LegacyAmFilterCategory, MERIT_DO_NOT_USE,
  887.     0, nil
  888.   );
  889. end.