PageRenderTime 31ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/jvcl/run/JvAVICapture.pas

http://my-chuanqi.googlecode.com/
Pascal | 1805 lines | 1276 code | 185 blank | 344 comment | 96 complexity | 4b022707e88b2094e4b608ad3aecd380 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. {-----------------------------------------------------------------------------
  2. The contents of this file are subject to the Mozilla Public License
  3. Version 1.1 (the "License"); you may not use this file except in compliance
  4. with the License. You may obtain a copy of the License at
  5. http://www.mozilla.org/MPL/
  6. Software distributed under the License is distributed on an "AS IS" basis,
  7. WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
  8. the specific language governing rights and limitations under the License.
  9. The Original Code is: JvAVICapture.PAS, released 2003-07-05.
  10. The Initial Developer of the Original Code is Olivier Sannier <obones att altern dott org>
  11. Portions created by Olivier Sannier are Copyright (C) 2003 Olivier Sannier.
  12. All Rights Reserved.
  13. Contributor(s): none to date
  14. Current Version: 0.4
  15. You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
  16. located at http://jvcl.sourceforge.net
  17. Description: This unit defines a component that you can drop on any form or
  18. frame and that will display the video stream captured by a video
  19. device installed under Windows. You can perform live previews,
  20. record movies (and save them to avi files) or even capture
  21. single frames. A direct access is provided to the frames so that
  22. you can process them if you want. This is an encapsulation of the
  23. AVICap API from Win32.
  24. Known Issues: none known
  25. -----------------------------------------------------------------------------}
  26. // $Id: JvAVICapture.pas 11161 2007-01-20 19:59:32Z obones $
  27. unit JvAVICapture;
  28. {$I jvcl.inc}
  29. {$I windowsonly.inc}
  30. interface
  31. uses
  32. {$IFDEF UNITVERSIONING}
  33. JclUnitVersioning,
  34. {$ENDIF UNITVERSIONING}
  35. Windows, Messages, VFW, MMSystem, SysUtils, Classes, Graphics, Controls,
  36. JvTypes;
  37. type
  38. TJvScrollPos = class(TPersistent)
  39. protected
  40. FLeft: Integer;
  41. FTop: Integer;
  42. published
  43. property Left: Integer read FLeft write FLeft;
  44. property Top: Integer read FTop write FTop;
  45. end;
  46. // The video format used by the video device
  47. TJvVideoFormat = class(TPersistent)
  48. protected
  49. FHWnd: HWND; // the AVICap window using this format
  50. FWidth: Cardinal; // width of the image
  51. FHeight: Cardinal; // height of the image
  52. FBitDepth: Cardinal; // bits per pixel (8-16-24-32...)
  53. FPixelFormat: TPixelFormat; // pixel format (RGB, BGR, YUV...)
  54. FCompression: Integer; // compression used
  55. public
  56. constructor Create; // Create the video format
  57. procedure Update; // Update from the AVICap window
  58. property Width: Cardinal read FWidth;
  59. property Height: Cardinal read FHeight;
  60. property BitDepth: Cardinal read FBitDepth;
  61. property PixelFormat: TPixelFormat read FPixelFormat;
  62. property Compression: Integer read FCompression;
  63. end;
  64. // The audio format used by the device
  65. TJvAudioFormat = class(TPersistent)
  66. protected
  67. FHWnd: HWND; // the AVICap window using this format
  68. FFormatTag: Cardinal; // the format tag (PCM or others...)
  69. FChannels: Cardinal; // number of channels (usually 1 or 2)
  70. FSamplesPerSec: Cardinal; // number of samples per second in the stream
  71. FAvgBytesPerSec: Cardinal; // the average number of bytes per second
  72. FBlockAlign: Cardinal; // size of the block to align on
  73. FBitsPerSample: Cardinal; // number of bits per sample
  74. FExtraSize: Cardinal; // size of the extra data
  75. FExtra: Pointer; // extra data for formats other than PCM
  76. public
  77. // creates the audio format object and initializes it
  78. constructor Create;
  79. // updates from the AVICap window
  80. procedure Update;
  81. // apply the format to the window, returns True if successfull
  82. function Apply: Boolean;
  83. // fill in a PWaveFormatEx structure to use with API calls
  84. procedure FillWaveFormatEx(var wfex: PWaveFormatEx);
  85. // run-time only property, see FSize
  86. property ExtraSize: Cardinal read FExtraSize write FExtraSize;
  87. // run-time only property, see FExtra
  88. property Extra: Pointer read FExtra write FExtra;
  89. published
  90. // see the relevant fields for details on the following properties
  91. property FormatTag: Cardinal read FFormatTag write FFormatTag;
  92. property Channels: Cardinal read FChannels write FChannels;
  93. property SamplesPerSec: Cardinal read FSamplesPerSec write FSamplesPerSec;
  94. property AvgBytesPerSec: Cardinal read FAvgBytesPerSec write FAvgBytesPerSec;
  95. property BlockAlign: Cardinal read FBlockAlign write FBlockAlign;
  96. property BitsPerSample: Cardinal read FBitsPerSample write FBitsPerSample;
  97. end;
  98. // a percentage
  99. TJvPercent = 0..100;
  100. // the number of audio buffers to use (maximum 10)
  101. TJvNumAudioBuffer = 0..10;
  102. // the type of a virtual key
  103. TJvVirtualKey = type Integer;
  104. // the capture settings to use to save a video stream to an AVI file
  105. TJvCaptureSettings = class(TPersistent)
  106. protected
  107. // the AVICap window that will use these settings and from which
  108. // we will get the values when we update them
  109. FHWnd: HWND;
  110. // if True, the API will popup a confirmation window when starting the
  111. // capture session allowing the user to choose to continue or not.
  112. FConfirmCapture: Boolean;
  113. // the delay in microsecond between two frames. This is a requested
  114. // value, it may not be fully respected by the driver when capturing
  115. FFrameDelay: Cardinal;
  116. // the percentage of frames dropped above which the capture will end
  117. // in an error state (too many drops having occured)
  118. FPercentDropForError: TJvPercent;
  119. // if True the capture session will be launched in a separate background
  120. // thread, not disabling the caller. Reentrance issues must then be
  121. // considered to avoid the user to launch twice the capture, for instance
  122. FYield: Boolean;
  123. // the requested number of video buffers. The actual number of allocated
  124. // buffers may well be smaller because of hardware limitations
  125. FNumVideoBuffer: Cardinal;
  126. // the requested number of audio buffers. The actual number of allocated
  127. // buffers may well be smaller because of hardware limitations
  128. FNumAudioBuffer: TJvNumAudioBuffer;
  129. // if True, the audio stream will also be captured
  130. FCaptureAudio: Boolean;
  131. // if True, a left mouse click will stop the capture session
  132. FAbortLeftMouse: Boolean;
  133. // if True, a right mouse click will stop the capture session
  134. FAbortRightMouse: Boolean;
  135. // if different from 0, a press on that virtual key will stop the
  136. // capture session
  137. FKeyAbort: TJvVirtualKey;
  138. // if True, the FTimeLimit parameter will be considered
  139. FLimitEnabled: Boolean;
  140. // the time limit for the capture session (in seconds). Will only be
  141. // considered if FLimitEnabled is True
  142. FTimeLimit: Cardinal;
  143. // if True, the capture will occur at twice the size specified in the
  144. // other parameters of this class.
  145. FStepCapture2x: Boolean;
  146. // the number of frames to sample and make the average of when using
  147. // a step capture
  148. FStepCaptureAverageFrames: Cardinal;
  149. // the size of an audio buffer
  150. FAudioBufferSize: Cardinal;
  151. // if True, the audio stream is the master one with respect to time
  152. // alignment. if False, the video stream is the master (recommanded)
  153. FAudioMaster: Boolean;
  154. // if True, the capture will controll a MCI device as its source
  155. FMCIControl: Boolean;
  156. // if True, the step capture is enabled on the MCI device
  157. // this is only considered if FMCIControl is True
  158. FMCIStep: Boolean;
  159. // time of the MCI device to start capture at
  160. // this is only considered if FMCIControl is True
  161. FMCIStartTime: Cardinal;
  162. // time of the MCI device to stop capture at
  163. // this is only considered if FMCIControl is True
  164. FMCIStopTime: Cardinal;
  165. // sets the FKeyAbort field
  166. procedure SetKeyAbort(nKeyAbort: TJvVirtualKey);
  167. // get and set the FPS property
  168. function GetFPS: Double;
  169. procedure SetFPS(const Value: Double);
  170. // set the FrameDelay property, ensuring the value is always
  171. // greater than 0
  172. procedure SetFrameDelay(const Value: Cardinal);
  173. public
  174. // creates and initializes the class
  175. constructor Create;
  176. // updates the class fields from the AVICap window
  177. procedure Update;
  178. // applies the class fields to the AVICap window, returns True if successful
  179. function Apply: Boolean;
  180. published
  181. // (rom) default values would be a good idea
  182. // please refer to the relevant field declarations for detail on the following properties
  183. property ConfirmCapture: Boolean read FConfirmCapture write FConfirmCapture;
  184. property FrameDelay: Cardinal read FFrameDelay write SetFrameDelay;
  185. property FPS: Double read GetFPS write SetFPS;
  186. property PercentDropForError: TJvPercent read FPercentDropForError write FPercentDropForError;
  187. property Yield: Boolean read FYield write FYield;
  188. property NumVideoBuffer: Cardinal read FNumVideoBuffer write FNumVideoBuffer;
  189. property NumAudioBuffer: TJvNumAudioBuffer read FNumAudioBuffer write FNumAudioBuffer;
  190. property CaptureAudio: Boolean read FCaptureAudio write FCaptureAudio;
  191. property AbortLeftMouse: Boolean read FAbortLeftMouse write FAbortLeftMouse;
  192. property AbortRightMouse: Boolean read FAbortRightMouse write FAbortRightMouse;
  193. property KeyAbort: TJvVirtualKey read FKeyAbort write SetKeyAbort;
  194. property LimitEnabled: Boolean read FLimitEnabled write FLimitEnabled;
  195. property TimeLimit: Cardinal read FTimeLimit write FTimeLimit;
  196. property StepCapture2x: Boolean read FStepCapture2x write FStepCapture2x;
  197. property StepCaptureAverageFrames: Cardinal read FStepCaptureAverageFrames write FStepCaptureAverageFrames;
  198. property AudioBufferSize: Cardinal read FAudioBufferSize write FAudioBufferSize;
  199. property AudioMaster: Boolean read FAudioMaster write FAudioMaster;
  200. property MCIControl: Boolean read FMCIControl write FMCIControl;
  201. property MCIStep: Boolean read FMCIStep write FMCIStep;
  202. property MCIStartTime: Cardinal read FMCIStartTime write FMCIStartTime;
  203. property MCIStopTime: Cardinal read FMCIStopTime write FMCIStopTime;
  204. end;
  205. // the type for the number of colors a palette can have
  206. TJvPaletteNbColors = 0..256;
  207. TJvPalette = class(TPersistent)
  208. protected
  209. FHWnd: HWND; // the AVICap window that will use these settings
  210. public
  211. // create the object
  212. constructor Create;
  213. // save the palette associated with the driver into the given file
  214. // and returns True upon success.
  215. function Save(FileName: string): Boolean;
  216. // loads the palette from the given file and returns True upon success
  217. // FHWnd must not be null
  218. function Load(FileName: string): Boolean;
  219. // paste the palette from the clipboard
  220. function PasteFromClipboard: Boolean;
  221. // automatically create the best palette from the first nbFrames frames with
  222. // a maximum of nbColors colors
  223. function AutoCreate(nbFrames: Integer; nbColors: TJvPaletteNbColors): Boolean;
  224. // Use this call from a frame callback and set the Flag to True to indicate that
  225. // the current frame must be considered when creating the palette. Continue
  226. // calling this method with Flag set to True as long as you need it.
  227. // Then call it again with Flag set to False, to finalize the palette and pass
  228. // it to the capture driver that will now use it.
  229. function ManuallyCreate(Flag: Boolean; nbColors: TJvPaletteNbColors): Boolean;
  230. end;
  231. // the driver index (-1 if not connected, 0-9 if connected as there are at most 10 drivers
  232. // according to Microsoft documentation. But there can be more than 1 source per driver...
  233. TJvDriverIndex = -1..9;
  234. // The exception triggered when an invalid index driver index is given
  235. EInvalidDriverIndexError = class(EJVCLException)
  236. public
  237. constructor Create(Index: TJvDriverIndex; MaxIndex: TJvDriverIndex);
  238. end;
  239. // what a driver can do on the system
  240. TJvDriverCaps = set of
  241. (dcOverlay, // overlay rendering
  242. dcDlgVideoSource, // display a dialog to choose video source
  243. dcDlgVideoFormat, // display a dialog to choose video format
  244. dcDlgVideoDisplay, // display a dialog to choose video display
  245. dcCaptureInitialized, // is the capture initialized
  246. dcSuppliesPalettes); // if the driver supplies palettes
  247. TJvUsedEvents = set of
  248. (ueCapControl, // the OnCapControl event will be triggered
  249. ueError, // the OnError event will be triggered
  250. ueFrame, // the OnFrame event will be triggered
  251. ueStatus, // the OnStatus event will be triggered
  252. ueVideoStream, // the OnVideoStream event will be triggered
  253. ueWaveStream, // the OnWaveStream event will be triggered
  254. ueYield); // the OnYield event will be triggered
  255. // the video dialog to display
  256. TJvVideoDialog =
  257. (vdSource, // the source dialog (only if dcDlgVideoSource is in the caps)
  258. vdFormat, // the format dialog (only if dcDlgVideoFormat is in the caps)
  259. vdDisplay, // the display dialog (only if dcDlgVideoDisplay is in the caps)
  260. vdCompression); // the compression dialog (with all the installed video codecs)
  261. // local type for the events
  262. PJvVideoHdr = PVIDEOHDR;
  263. PJvWaveHdr = PWaveHdr;
  264. // forward declaration for the events
  265. TJvAVICapture = class;
  266. // the event triggered in case of an error
  267. // Sender is the TJvAVICapture component triggering the event
  268. // nErr is the error number
  269. // Str is the string associated with that error
  270. TOnError = procedure(Sender: TJvAVICapture; nErr: Integer; Str: string) of object;
  271. // the event triggered in case of a status change (use it to follow progress)
  272. // Sender is the TJvAVICapture component triggering the event
  273. // nId is the id of the status change (see win32 API for more details)
  274. // Str is the string associated with that status change
  275. TOnStatus = procedure(Sender: TJvAVICapture; nId: Integer; Str: string) of object;
  276. // the event triggerred when the driver is yielding. a good place to put a
  277. // call to Application.ProcessMessages
  278. // Sender is the TJvAVICapture component triggering the event
  279. TOnYield = procedure(Sender: TJvAVICapture) of object;
  280. // the event trigerred when a frame is ready to be written to disk during streaming capture
  281. // Sender is the TJvAVICapture component triggering the event
  282. // videoHdr is the video header describing the stream
  283. TOnVideoStream = procedure(Sender: TJvAVICapture; videoHdr: PJvVideoHdr) of object;
  284. // the event trigerred when a frame is ready, in a non streaming capture session
  285. TOnFrame = TOnVideoStream;
  286. // the event trigerred when an audio buffer is ready to be written do disk during streaming capture
  287. // Sender is the TJvAVICapture component triggering the event
  288. // audioHdr is the audio header describing the stream
  289. TOnWaveStream = procedure(Sender: TJvAVICapture; waveHdr: PJvWaveHdr) of object;
  290. // the event triggered when you want to use precise capture control
  291. // Sender is the TJvAVICapture component triggering the event
  292. // state is the state in which the capture is (refer to API for details)
  293. // Result is to be set to True if capture must continue, False if it must stop
  294. TOnCapControl = procedure(Sender: TJvAVICapture; nState: Integer; var Result: Boolean) of object;
  295. // the main component. Just drop it on a form or a frame, set the driver property, set previewing to
  296. // True and you should see the video coming through (even in design mode !)
  297. TJvAVICapture = class(TWinControl)
  298. protected
  299. FCaptureSettings: TJvCaptureSettings; // the capture settings
  300. FCapturing: Boolean; // True if capture is happening
  301. FConnected: Boolean; // True if connected to a driver
  302. FDrivers: TStringList; // the available drivers as a TStringList
  303. FDriverCaps: TJvDriverCaps; // the current driver capabilities
  304. FHWnd: HWND; // the handle to the AviCap window
  305. FNoFile: Boolean; // True if not capturing to a file
  306. FOverlaying: Boolean; // True if using overlay display
  307. FPreviewFrameDelay: Cardinal; // the time between two preview frames (ms)
  308. FPreviewing: Boolean; // True if previewing
  309. FSingleFrameCapturing: Boolean; // True if capturing using single frame capture
  310. FTitle: string; // the title of the AVICap window
  311. FVideoLeft: Integer; // the left coordinate of the displayed video
  312. FVideoTop: Integer; // the top coordinate of the displayed video
  313. // the user supplied event handlers
  314. // see respective types for details
  315. FOnError: TOnError;
  316. FOnStatus: TOnStatus;
  317. FOnYield: TOnYield;
  318. FOnFrame: TOnFrame;
  319. FOnVideoStream: TOnVideoStream;
  320. FOnWaveStream: TOnWaveStream;
  321. FOnCapControl: TOnCapControl;
  322. FFileName: string; // the filename for the capture file
  323. FFileSizeAlloc: Cardinal; // the size to allocate for the capture file
  324. FUsedEvents: TJvUsedEvents; // which events are used
  325. FCaptureStatus: TCAPSTATUS; // the state of the current capture
  326. FVideoFormat: TJvVideoFormat; // the current video format used (or to be used)
  327. FAudioFormat: TJvAudioFormat; // the current audio format used (or to be used)
  328. FScrollPos: TJvScrollPos; // the scrolling position in the window
  329. FPalette: TJvPalette; // the palette in use
  330. FDriverIndex: TJvDriverIndex; // the driver index (-1 if not connected)
  331. // the Pointer to the previous WndProc of the AviCap window
  332. FPreviousWndProc: Pointer;
  333. // window creation stuff, where the AviCap window is created:
  334. // what is done is that the component inherits from TWinControl and as such
  335. // has its own handle. We then create the AviCap window and set it as a child
  336. // of the TWinControl. This allows to take advantage of all the VCL handling
  337. // for design time, parent, ownership... and we can focus on using the
  338. // AviCap window to do the capture
  339. procedure CreateWindowHandle(const Params: TCreateParams); override;
  340. // destroys the AviCap window just before letting the VCL destroy the handle
  341. // for the TWinControl
  342. procedure DestroyWindowHandle; override;
  343. // Resizes the internal window that is used to display the AviCap content.
  344. procedure ResizeAviCapWindow(Width, Height: Integer);
  345. // We enforce the size of the window to be equal to the
  346. // video frame in this method as it is the place where it
  347. // should be done, rather than doing it in SetBounds
  348. function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override;
  349. // sets the title of the AviCap window
  350. procedure SetTitle(nTitle: string);
  351. // sets the preview frame delay (the time between two frames)
  352. procedure SetPreviewFrameDelay(nPreviewFrameDelay: Cardinal);
  353. // sets and gets the preview frame rate in frames per second
  354. procedure SetPreviewFPS(nPreviewFPS: Double);
  355. function GetPreviewFPS: Double;
  356. // sets the previewing property and starts or stop previewing accordingly
  357. procedure SetPreviewing(nPreviewing: Boolean);
  358. // sets and gets the filename for capture
  359. procedure SetFileName(nFileName: TFileName);
  360. function GetFileName: TFileName;
  361. // delivers FDrivers as TStrings for property
  362. function GetDrivers: TStrings;
  363. // sets the file size to allocate before capture. This might speed up capture as
  364. // the file won't need to be grown
  365. procedure SetFileSizeAlloc(nFileSizeAlloc: Cardinal);
  366. // sets the used events and updates the related values in the AviCap window
  367. procedure SetUsedEvents(nUsedEvents: TJvUsedEvents);
  368. // sets the overlaying rendering. May do nothing if driver cannot do overlay rendering
  369. procedure SetOverlaying(nOverlaying: Boolean);
  370. // returns the name of the driver or an empty string if FConnected is False
  371. function GetDriverName: string;
  372. // returns the version of the driver or an empty string if FConnected is False
  373. function GetDriverVersion: string;
  374. // set the scrolling position in the AviCap window. Useful if the frame is larger than
  375. // the actual size of the control
  376. procedure SetScrollPos(nScrollPos: TJvScrollPos);
  377. // sets and gets the MCI device used with this AviCap component (may well be empty)
  378. procedure SetMCIDevice(nMCIDevice: string);
  379. function GetMCIDevice: string;
  380. // sets the driver index to the given value and tries to connect. If connection
  381. // is not possible, will not change the current value
  382. procedure SetDriverIndex(nIndex: TJvDriverIndex);
  383. // tries to starts or stops capture according to the value
  384. // immediately check the value of FCapturing to see if capture
  385. // started succesfuly
  386. procedure SetCapturing(nCapturing: Boolean);
  387. // tries starts or stops single frame capture according to the value
  388. // immediately check the value of FSingleFrameCapturing to see
  389. // if capture started succesfuly
  390. procedure SetSingleFrameCapturing(const Value: Boolean);
  391. // sets the FNoFile flag
  392. procedure SetNoFile(nNoFile: Boolean);
  393. // sets the FVideoLeft and FVideoTop values and also
  394. // makes the required capCall
  395. procedure SetVideoLeft(const Value: Integer);
  396. procedure SetVideoTop(const Value: Integer);
  397. // updates the content of the FDriverCaps field
  398. procedure UpdateCaps;
  399. // updates the content of the FCaptureStatus field
  400. procedure UpdateCaptureStatus;
  401. // stops and start using callbacks. This is required as it appears that the
  402. // callbacks are still called after a capture session has been stopped.
  403. procedure StopCallbacks;
  404. procedure RestartCallbacks;
  405. // Functions to be called from the callbacks that will trigger the user events
  406. procedure DoError(ErrId: Integer; Str: string);
  407. procedure DoStatus(nId: Integer; Str: string);
  408. procedure DoYield;
  409. procedure DoFrame(videoHdr: PVIDEOHDR);
  410. procedure DoVideoStream(videoHdr: PVIDEOHDR);
  411. procedure DoWaveStream(waveHdr: PWaveHdr);
  412. procedure DoCapControl(nState: Integer; var AResult: Boolean);
  413. public
  414. // creates the component and initializes the different fields
  415. constructor Create(AOwner: TComponent); override;
  416. // destroys the component
  417. destructor Destroy; override;
  418. // sets the size of the component
  419. procedure SetBounds(nLeft, nTop, nWidth, nHeight: Integer); override;
  420. // enumarate the drivers and populates the FDrivers list
  421. procedure EnumDrivers;
  422. // tries to connect to the given driver. Returns True if successful, False otherwise
  423. function Connect(Driver: TJvDriverIndex): Boolean;
  424. // tries to disconnect from a driver. Returns True if successful, False otherwise
  425. function Disconnect: Boolean;
  426. // shows the given dialog and returns True if user pressed ok. If the driver
  427. // cannot show the given dialog...
  428. function ShowDialog(Dialog: TJvVideoDialog): Boolean;
  429. // starts and stop previewing, returning True upon success
  430. function StartPreview: Boolean;
  431. function StopPreview: Boolean;
  432. // start capturing to a file using streaming capture
  433. function StartCapture: Boolean;
  434. // start capturing without using a file. You should use the OnVideoStream event in that
  435. // case to process the frames yourself. This might be useful in a videoconferencing
  436. // software, where you transfer the frames directly
  437. function StartCaptureNoFile: Boolean;
  438. // stops the capture properly
  439. function StopCapture: Boolean;
  440. // aborts the capture, leaving the file unusable
  441. function AbortCapture: Boolean;
  442. // starts frame by frame capture (non streaming)
  443. function StartSingleFrameCapture: Boolean;
  444. // captures one frame in a frame by frame capture session
  445. function CaptureFrame: Boolean;
  446. // stops frame by frame capture
  447. function StopSingleFrameCapture: Boolean;
  448. // starts and stop overlay rendering, returns True if successful
  449. function StartOverlay: Boolean;
  450. function StopOverlay: Boolean;
  451. // applies the capture settings, returns True if successful
  452. function ApplyCaptureSettings: Boolean;
  453. // applies the audio format settings, returns True if successful
  454. function ApplyAudioFormat: Boolean;
  455. // saves the stream under the given filename
  456. function SaveAs(Name: string): Boolean;
  457. // sets information chunks in the output file
  458. function SetInfoChunk(const Chunk: TCAPINFOCHUNK): Boolean;
  459. // saves the latest captured frame to a DIB file
  460. function SaveDIB(Name: string): Boolean;
  461. // copies the latest frame to the clipboard
  462. function CopyToClipboard: Boolean;
  463. // grabs one frame, not using any capture session
  464. // if stop is True, previewing and overlaying are stopped
  465. // if stop is False, previewing and overlaying are left untouched
  466. function GrabFrame(Stop: Boolean): Boolean;
  467. // public properties (run-time only), refer to fields and methods descriptions
  468. // for details on the usage
  469. property CaptureStatus: TCAPSTATUS read FCaptureStatus;
  470. property Capturing: Boolean read FCapturing write SetCapturing;
  471. property Connected: Boolean read FConnected;
  472. property DriverCaps: TJvDriverCaps read FDriverCaps;
  473. property DriverName: string read GetDriverName;
  474. property DriverVersion: string read GetDriverVersion;
  475. property Drivers: TStrings read GetDrivers;
  476. property Handle: HWND read FHWnd;
  477. property Palette: TJvPalette read FPalette;
  478. property SingleFrameCapturing: Boolean read FSingleFrameCapturing write SetSingleFrameCapturing;
  479. property VideoFormat: TJvVideoFormat read FVideoFormat;
  480. published
  481. // published properties, refer to the field and methods descriptions for details
  482. property AudioFormat: TJvAudioFormat read FAudioFormat;
  483. property CaptureSettings: TJvCaptureSettings read FCaptureSettings;
  484. property DriverIndex: TJvDriverIndex read FDriverIndex write SetDriverIndex default -1;
  485. property FileName: TFileName read GetFileName write SetFileName;
  486. property FileSizeAlloc: Cardinal read FFileSizeAlloc write SetFileSizeAlloc default 0;
  487. property MCIDevice: string read GetMCIDevice write SetMCIDevice;
  488. property NoFile: Boolean read FNoFile write SetNoFile default False;
  489. property Overlaying: Boolean read FOverlaying write SetOverlaying default False;
  490. property PreviewFrameDelay: Cardinal read FPreviewFrameDelay write SetPreviewFrameDelay default 50;
  491. property PreviewFPS: Double read GetPreviewFPS write SetPreviewFPS;
  492. property Previewing: Boolean read FPreviewing write SetPreviewing default False;
  493. property ScrollPos: TJvScrollPos read FScrollPos write SetScrollPos;
  494. property Title: string read FTitle write SetTitle;
  495. property UsedEvents: TJvUsedEvents read FUsedEvents write SetUsedEvents default [];
  496. property VideoLeft: Integer read FVideoLeft write SetVideoLeft default 0;
  497. property VideoTop: Integer read FVideoTop write SetVideoTop default 0;
  498. // inherited properties getting published
  499. property AutoSize;
  500. property ParentShowHint;
  501. property ShowHint;
  502. property Visible;
  503. // the events, refer to the fields decriptions for details
  504. property OnError: TOnError read FOnError write FOnError;
  505. property OnStatus: TOnStatus read FOnStatus write FOnStatus;
  506. property OnYield: TOnYield read FOnYield write FOnYield;
  507. property OnFrame: TOnFrame read FOnFrame write FOnFrame;
  508. property OnVideoStream: TOnVideoStream read FOnVideoStream write FOnVideoStream;
  509. property OnWaveStream: TOnWaveStream read FOnWaveStream write FOnWaveStream;
  510. property OnCapControl: TOnCapControl read FOnCapControl write FOnCapControl;
  511. end;
  512. {$IFDEF UNITVERSIONING}
  513. const
  514. UnitVersioning: TUnitVersionInfo = (
  515. RCSfile: '$URL: https://jvcl.svn.sourceforge.net:443/svnroot/jvcl/trunk/jvcl/run/JvAVICapture.pas $';
  516. Revision: '$Revision: 11161 $';
  517. Date: '$Date: 2007-01-20 11:59:32 -0800 (Sat, 20 Jan 2007) $';
  518. LogPath: 'JVCL\run'
  519. );
  520. {$ENDIF UNITVERSIONING}
  521. implementation
  522. uses
  523. Math, // for Min and Max
  524. JvResources;
  525. const
  526. // minimal height and width of the display window
  527. cMinHeight = 20;
  528. cMinWidth = 20;
  529. { Global functions }
  530. // an helper function that tells if the window is connected to a driver
  531. function capDriverConnected(hWnd: HWND): Boolean;
  532. var
  533. TmpName: array [0..MAX_PATH] of Char;
  534. begin
  535. Result := capDriverGetName(hWnd, TmpName, SizeOf(TmpName));
  536. end;
  537. { This is the custom window procedure, which replaces the one originally associated
  538. with the AviCap window. all we do is pass the messages to the TWinControl
  539. containing the AviCap window so that it can resize and move itself.
  540. Then we pass the message to the original window procedure for it to handle the
  541. messages it needs to perform the video capture
  542. }
  543. function CustomWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
  544. var
  545. SelfObj: TJvAVICapture;
  546. begin
  547. Result := 0;
  548. // get the Pointer to self from the window user data
  549. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  550. if SelfObj <> nil then
  551. begin
  552. // send the message to the containing window,
  553. // except for WM_NCHITTEST during design
  554. // This will prevent 100% processor usage when the mouse is kept over
  555. // the control during design time
  556. // Note: We MUST convert SelfObj to a TWinControl as the Handle
  557. // property of TJvAVICapture returns the handle of the AVICap window
  558. // thus leading to an infinite loop if we were to use it...
  559. if (Msg <> WM_NCHITTEST) or not (csDesigning in SelfObj.ComponentState) then
  560. PostMessage(TWinControl(SelfObj).Handle, Msg, wParam, lParam);
  561. // sending the message to the original window proc
  562. Result := CallWindowProc(SelfObj.FPreviousWndProc, hWnd, Msg, wParam, lParam);
  563. end;
  564. end;
  565. { Callbacks }
  566. // This is the callback called in case of an error
  567. // will only be called if the user chose so with ueError
  568. function ErrorCallback(hWnd: HWND; ErrId: Integer; Str: LPSTR): LRESULT; stdcall;
  569. var
  570. SelfObj: TJvAVICapture;
  571. begin
  572. // clear previous error if required
  573. if ErrId = 0 then
  574. begin
  575. Result := LRESULT(Ord(True));
  576. Exit;
  577. end;
  578. // get the Pointer to self from the window user data
  579. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  580. if SelfObj <> nil then
  581. SelfObj.DoError(ErrId, Str);
  582. Result := LRESULT(Ord(True));
  583. end;
  584. // This is the callback called in case of a status change
  585. // will only be called if the user chose so with ueStatus
  586. function StatusCallback(hWnd: HWND; nId: Integer; Str: LPSTR): LRESULT; stdcall;
  587. var
  588. SelfObj: TJvAVICapture;
  589. begin
  590. // get the Pointer to self from the window user data
  591. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  592. if SelfObj <> nil then
  593. SelfObj.DoStatus(nId, Str);
  594. Result := LRESULT(Ord(True));
  595. end;
  596. // This is the callback called in case of yielding
  597. // will only be called if the user chose so with ueYield
  598. function YieldCallback(hWnd: HWND): LRESULT; stdcall;
  599. var
  600. SelfObj: TJvAVICapture;
  601. begin
  602. // get the Pointer to self from the window user data
  603. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  604. if SelfObj <> nil then
  605. SelfObj.DoYield;
  606. Result := LRESULT(Ord(True));
  607. end;
  608. // This is the callback called in case a new frame is available while a non
  609. // streaming capture is in progress
  610. // will only be called if the user chose so with ueFrame
  611. function FrameCallback(hWnd: HWND; videoHdr: PVIDEOHDR): LRESULT; stdcall;
  612. var
  613. SelfObj: TJvAVICapture;
  614. begin
  615. // get the Pointer to self from the window user data
  616. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  617. if SelfObj <> nil then
  618. SelfObj.DoFrame(videoHdr);
  619. Result := LRESULT(Ord(True));
  620. end;
  621. // This is the callback called when a frame is available, just before being
  622. // written to disk, only if using stream capture
  623. // will only be called if the user chose so with ueVideoStream
  624. function VideoStreamCallback(hWnd: HWND; videoHdr: PVIDEOHDR): LRESULT; stdcall;
  625. var
  626. SelfObj: TJvAVICapture;
  627. begin
  628. // get the Pointer to self from the window user data
  629. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  630. if SelfObj <> nil then
  631. SelfObj.DoVideoStream(videoHdr);
  632. Result := LRESULT(Ord(True));
  633. end;
  634. // this is the callback when an audio buffer is ready to be written to disk
  635. // and only when using streaming capture
  636. // will only be called if user chose so with ueWaveStream
  637. function WaveStreamCallback(hWnd: HWND; waveHdr: PWaveHdr): LRESULT; stdcall;
  638. var
  639. SelfObj: TJvAVICapture;
  640. begin
  641. // get the Pointer to self from the window user data
  642. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  643. if SelfObj <> nil then
  644. SelfObj.DoWaveStream(waveHdr);
  645. Result := LRESULT(Ord(True));
  646. end;
  647. // this is the callback called when a precise capture control event has
  648. // occured. Only called if user chose so with ueCapControl
  649. function CapControlCallback(hWnd: HWND; nState: Integer): LRESULT; stdcall;
  650. var
  651. SelfObj: TJvAVICapture;
  652. res: Boolean;
  653. begin
  654. res := True;
  655. // get the Pointer to self from the window user data
  656. SelfObj := TJvAVICapture(GetWindowLong(hWnd, GWL_USERDATA));
  657. if SelfObj <> nil then
  658. SelfObj.DoCapControl(nState, res);
  659. Result := LRESULT(Ord(res));
  660. end;
  661. //=== { TJvVideoFormat } =====================================================
  662. constructor TJvVideoFormat.Create;
  663. begin
  664. inherited Create;
  665. FHWnd := 0;
  666. end;
  667. procedure TJvVideoFormat.Update;
  668. var
  669. BmpInfo: BITMAPINFOHEADER;
  670. begin
  671. if (FHWnd <> 0) and capDriverConnected(FHWnd) then
  672. begin
  673. // get format from the AviCap window
  674. capGetVideoFormat(FHWnd, @BmpInfo, SizeOf(BmpInfo));
  675. // update the internal values
  676. FWidth := BmpInfo.biWidth;
  677. FHeight := BmpInfo.biHeight;
  678. FBitDepth := BmpInfo.biBitCount;
  679. FCompression := BmpInfo.biCompression;
  680. case BitDepth of
  681. 0:
  682. FPixelFormat := pfDevice;
  683. 1:
  684. FPixelFormat := pf1bit;
  685. 4:
  686. FPixelFormat := pf4bit;
  687. 8:
  688. FPixelFormat := pf8bit;
  689. 16:
  690. FPixelFormat := pf15bit;
  691. 24:
  692. FPixelFormat := pf24bit;
  693. 32:
  694. FPixelFormat := pf32bit;
  695. else
  696. FPixelFormat := pfCustom;
  697. end;
  698. end;
  699. end;
  700. //=== { TJvAudioFormat } =====================================================
  701. constructor TJvAudioFormat.Create;
  702. begin
  703. inherited Create;
  704. FHWnd := 0;
  705. FExtra := nil;
  706. end;
  707. procedure TJvAudioFormat.Update;
  708. var
  709. Info: tWAVEFORMATEX;
  710. begin
  711. if (FHWnd <> 0) and capDriverConnected(FHWnd) then
  712. begin
  713. // gets the format from the AviCap window
  714. capGetAudioFormat(FHWnd, @Info, SizeOf(Info));
  715. // sets the internal values
  716. FFormatTag := Info.wFormatTag;
  717. FChannels := Info.nChannels;
  718. FSamplesPerSec := Info.nSamplesPerSec;
  719. FAvgBytesPerSec := Info.nAvgBytesPerSec;
  720. FBlockAlign := Info.nBlockAlign;
  721. FBitsPerSample := Info.wBitsPerSample;
  722. FExtraSize := Info.cbSize;
  723. // if there is extra data, save it too
  724. if FExtraSize > 0 then
  725. begin
  726. // if there was extra data saved before, free it before
  727. if FExtra <> nil then
  728. FreeMem(FExtra);
  729. GetMem(FExtra, ExtraSize);
  730. CopyMemory(FExtra, (PChar(@Info)) + SizeOf(tWAVEFORMATEX), FExtraSize);
  731. end;
  732. end;
  733. end;
  734. function TJvAudioFormat.Apply: Boolean;
  735. var
  736. pwfex: PWaveFormatEx;
  737. begin
  738. Result := False;
  739. if FHWnd <> 0 then
  740. begin
  741. FillWaveFormatEx(pwfex);
  742. Result := capSetAudioFormat(FHWnd, pwfex, SizeOf(tWAVEFORMATEX) + pwfex^.cbSize);
  743. end;
  744. end;
  745. procedure TJvAudioFormat.FillWaveFormatEx(var wfex: PWaveFormatEx);
  746. begin
  747. case FormatTag of
  748. WAVE_FORMAT_PCM:
  749. begin
  750. GetMem(wfex, SizeOf(tWAVEFORMATEX));
  751. wfex^.wFormatTag := FFormatTag;
  752. // ensure maximum 2 channels
  753. wfex^.nChannels := FChannels mod 3;
  754. wfex^.nSamplesPerSec := FSamplesPerSec;
  755. // ensure 8 or 16 bits
  756. wfex^.wBitsPerSample := ((FBitsPerSample div 8) mod 3) * 8;
  757. // using rules defined in Documentation
  758. wfex^.nBlockAlign := wfex.nChannels * wfex.wBitsPerSample div 8;
  759. wfex^.nAvgBytesPerSec := wfex.nSamplesPerSec * wfex.nBlockAlign;
  760. wfex^.cbSize := 0;
  761. end;
  762. else
  763. GetMem(wfex, SizeOf(tWAVEFORMATEX) + FExtraSize);
  764. wfex^.wFormatTag := FFormatTag;
  765. wfex^.nChannels := FChannels;
  766. wfex^.nSamplesPerSec := FSamplesPerSec;
  767. wfex^.nAvgBytesPerSec := FAvgBytesPerSec;
  768. wfex^.nBlockAlign := FBlockAlign;
  769. wfex^.wBitsPerSample := FBitsPerSample;
  770. wfex^.cbSize := FExtraSize;
  771. // copy Extra to the end of the structure
  772. CopyMemory((PChar(@wfex)) + SizeOf(tWAVEFORMATEX), FExtra, FExtraSize);
  773. end;
  774. end;
  775. //=== { TJvCaptureSettings } =================================================
  776. constructor TJvCaptureSettings.Create;
  777. begin
  778. inherited Create;
  779. FHWnd := 0;
  780. FFrameDelay := 1;
  781. end;
  782. procedure TJvCaptureSettings.SetKeyAbort(nKeyAbort: TJvVirtualKey);
  783. var
  784. Modifiers: Word;
  785. begin
  786. // Unregister any previous hotkey
  787. if FKeyAbort <> 0 then
  788. UnregisterHotKey(FHWnd, 0);
  789. // register hotkey, only if needed
  790. if nKeyAbort <> 0 then
  791. begin
  792. Modifiers := 0;
  793. if (nKeyAbort and $4000) <> 0 then
  794. Modifiers := Modifiers or MOD_SHIFT;
  795. if (nKeyAbort and $8000) <> 0 then
  796. Modifiers := Modifiers or MOD_CONTROL;
  797. if RegisterHotKey(FHWnd, 0, Modifiers, nKeyAbort and $FF) then
  798. FKeyAbort := nKeyAbort;
  799. end
  800. else
  801. FKeyAbort := nKeyAbort;
  802. end;
  803. procedure TJvCaptureSettings.Update;
  804. var
  805. Parms: TCAPTUREPARMS;
  806. begin
  807. if FHWnd <> 0 then
  808. begin
  809. // get capture settings from window
  810. capCaptureGetSetup(FHWnd, @Parms, SizeOf(Parms));
  811. // udapte internal settings
  812. with Parms do
  813. begin
  814. FFrameDelay := dwRequestMicroSecPerFrame;
  815. // FFramesPerSec := 1/dwRequestMicroSecPerFrame*1E6;
  816. FConfirmCapture := fMakeUserHitOKToCapture;
  817. FPercentDropForError := wPercentDropForError;
  818. FYield := FYield;
  819. FNumVideoBuffer := wNumVideoRequested;
  820. FCaptureAudio := FCaptureAudio;
  821. FNumAudioBuffer := wNumAudioRequested;
  822. FAbortLeftMouse := FAbortLeftMouse;
  823. FAbortRightMouse := FAbortRightMouse;
  824. FKeyAbort := vKeyAbort;
  825. FLimitEnabled := FLimitEnabled;
  826. FTimeLimit := wTimeLimit;
  827. FStepCapture2x := fStepCaptureAt2x;
  828. FStepCaptureAverageFrames := wStepCaptureAverageFrames;
  829. FAudioBufferSize := dwAudioBufferSize;
  830. FAudioMaster := (AVStreamMaster = AVSTREAMMASTER_AUDIO);
  831. FMCIControl := FMCIControl;
  832. FMCIStep := fStepMCIDevice;
  833. FMCIStartTime := dwMCIStartTime;
  834. FMCIStopTime := dwMCIStopTime;
  835. end;
  836. end;
  837. end;
  838. function TJvCaptureSettings.Apply: Boolean;
  839. var
  840. Parms: TCAPTUREPARMS;
  841. begin
  842. Result := False;
  843. if FHWnd <> 0 then
  844. begin
  845. // get original values from window
  846. capCaptureGetSetup(FHWnd, @Parms, SizeOf(Parms));
  847. // set our own values
  848. with Parms do
  849. begin
  850. dwRequestMicroSecPerFrame := FFrameDelay;
  851. fMakeUserHitOKToCapture := ConfirmCapture;
  852. wPercentDropForError := PercentDropForError;
  853. FYield := Yield;
  854. wNumVideoRequested := NumVideoBuffer;
  855. FCaptureAudio := CaptureAudio;
  856. wNumAudioRequested := NumAudioBuffer;
  857. FAbortLeftMouse := AbortLeftMouse;
  858. FAbortRightMouse := AbortRightMouse;
  859. vKeyAbort := FKeyAbort;
  860. FLimitEnabled := LimitEnabled;
  861. wTimeLimit := TimeLimit;
  862. fStepCaptureAt2x := StepCapture2x;
  863. wStepCaptureAverageFrames := StepCaptureAverageFrames;
  864. dwAudioBufferSize := AudioBufferSize;
  865. if AudioMaster then
  866. AVStreamMaster := AVSTREAMMASTER_AUDIO
  867. else
  868. AVStreamMaster := AVSTREAMMASTER_NONE;
  869. FMCIControl := Self.FMCIControl;
  870. fStepMCIDevice := Self.FMCIStep;
  871. dwMCIStartTime := FMCIStartTime;
  872. dwMCIStopTime := FMCIStopTime;
  873. end;
  874. // apply new settings
  875. Result := capCaptureSetSetup(FHWnd, @Parms, SizeOf(Parms));
  876. end;
  877. end;
  878. function TJvCaptureSettings.GetFPS: Double;
  879. begin
  880. Result := 1 / FFrameDelay * 1.0E6;
  881. end;
  882. procedure TJvCaptureSettings.SetFPS(const Value: Double);
  883. begin
  884. FFrameDelay := Round(1.0E6 / Value);
  885. end;
  886. procedure TJvCaptureSettings.SetFrameDelay(const Value: Cardinal);
  887. begin
  888. // to avoid division by 0 and stupid value for a time delay
  889. // between two frames
  890. if Value = 0 then
  891. FFrameDelay := 1
  892. else
  893. FFrameDelay := Value;
  894. end;
  895. //=== { TJvPalette } =========================================================
  896. constructor TJvPalette.Create;
  897. begin
  898. inherited Create;
  899. FHWnd := 0;
  900. end;
  901. function TJvPalette.Load(FileName: string): Boolean;
  902. begin
  903. Result := (FHWnd <> 0) and capPaletteOpen(FHWnd, PChar(FileName));
  904. end;
  905. function TJvPalette.Save(FileName: string): Boolean;
  906. begin
  907. Result := (FHWnd <> 0) and capPaletteSave(FHWnd, PChar(FileName));
  908. end;
  909. function TJvPalette.PasteFromClipboard: Boolean;
  910. begin
  911. Result := (FHWnd <> 0) and capPalettePaste(FHWnd);
  912. end;
  913. function TJvPalette.AutoCreate(nbFrames: Integer; nbColors: TJvPaletteNbColors): Boolean;
  914. begin
  915. Result := (FHWnd <> 0) and capPaletteAuto(FHWnd, nbFrames, nbColors);
  916. end;
  917. function TJvPalette.ManuallyCreate(Flag: Boolean; nbColors: TJvPaletteNbColors): Boolean;
  918. begin
  919. Result := (FHWnd <> 0) and capPaletteManual(FHWnd, Flag, nbColors);
  920. end;
  921. //=== { TJvAVICapture } ======================================================
  922. constructor TJvAVICapture.Create(AOwner: TComponent);
  923. begin
  924. inherited Create(AOwner);
  925. FScrollPos := TJvScrollPos.Create;
  926. // Not connected yet
  927. FDriverIndex := -1;
  928. FFileSizeAlloc := 0;
  929. FOverlaying := False;
  930. FPreviewing := False;
  931. FUsedEvents := [];
  932. FVideoLeft := 0;
  933. FVideoTop := 0;
  934. FDrivers := TStringList.Create;
  935. // Preview frame delay = 50ms between frames (20 frames per second)
  936. FPreviewFrameDelay := 50;
  937. FVideoFormat := TJvVideoFormat.Create;
  938. FAudioFormat := TJvAudioFormat.Create;
  939. // Default to PCM, 11.025khz 8 bit Mono
  940. with FAudioFormat do
  941. begin
  942. FormatTag := WAVE_FORMAT_PCM;
  943. Channels := 1;
  944. BitsPerSample := 8;
  945. SamplesPerSec := 11025;
  946. end;
  947. FCaptureSettings := TJvCaptureSettings.Create;
  948. FPalette := TJvPalette.Create;
  949. SetBounds(0, 0, 320, 240);
  950. EnumDrivers;
  951. // set all events to 'used'
  952. UsedEvents := [ueError, ueStatus, ueYield, ueFrame, ueVideoStream, ueWaveStream, ueCapControl];
  953. end;
  954. destructor TJvAVICapture.Destroy;
  955. begin
  956. Disconnect;
  957. FDrivers.Free;
  958. FCaptureSettings.Free;
  959. FAudioFormat.Free;
  960. FVideoFormat.Free;
  961. FPalette.Free;
  962. FScrollPos.Free;
  963. inherited Destroy;
  964. end;
  965. procedure TJvAVICapture.CreateWindowHandle(const Params: TCreateParams);
  966. begin
  967. // ensure the TWinControl is fully created first
  968. inherited CreateWindowHandle(Params);
  969. // no hint to show
  970. //ParentShowHint := False;
  971. //ShowHint := False;
  972. // create the AviCap window
  973. FHWnd := capCreateCaptureWindow(
  974. PChar(Title), // use the user defined title
  975. WS_VISIBLE or // window is visible
  976. WS_CHILD and // it is a child window
  977. not WS_CAPTION and // it has no caption
  978. not WS_BORDER, // it has no border
  979. 0, // 0 left coordinate
  980. 0, // 0 top coordinate
  981. 320, // width defaults to 320
  982. 240, // height defaults to 240
  983. inherited Handle, // child of the TWinControl
  984. 0); // window identifier
  985. // place the Pointer to Self in the user data
  986. SetWindowLong(FHWnd, GWL_USERDATA, Integer(Self));
  987. // replace the WndProc to be ours
  988. FPreviousWndProc := Pointer(GetWindowLong(FHWnd, GWL_WNDPROC));
  989. SetWindowLong(FHWnd, GWL_WNDPROC, Integer(@CustomWndProc));
  990. // updates the FHWnd member of audio format, capture settings, palette and video format
  991. // yes, they are private members, but they can still be accessed by a foreign class
  992. // because the access is done in the same pas file !
  993. FAudioFormat.FHWnd := FHWnd;
  994. FCaptureSettings.FHWnd := FHWnd;
  995. FPalette.FHWnd := FHWnd;
  996. FVideoFormat.FHWnd := FHWnd;
  997. // sets the callbacks
  998. UsedEvents := FUsedEvents;
  999. end;
  1000. procedure TJvAVICapture.DestroyWindowHandle;
  1001. begin
  1002. // restore the window proc
  1003. SetWindowLong(FHWnd, GWL_WNDPROC, Integer(FPreviousWndProc));
  1004. // destroy the AviCap Window
  1005. DestroyWindow(FHWnd);
  1006. // let the TWinControl window be destroyed
  1007. inherited DestroyWindowHandle;
  1008. end;
  1009. procedure TJvAVICapture.SetTitle(nTitle: string);
  1010. begin
  1011. if FHWnd <> 0 then
  1012. begin
  1013. FTitle := nTitle;
  1014. SetWindowText(FHWnd, PChar(FTitle));
  1015. end;
  1016. end;
  1017. procedure TJvAVICapture.SetPreviewFrameDelay(nPreviewFrameDelay: Cardinal);
  1018. begin
  1019. FPreviewFrameDelay := nPreviewFrameDelay;
  1020. if Previewing then
  1021. begin
  1022. StopPreview;
  1023. StartPreview;
  1024. end;
  1025. end;
  1026. procedure TJvAVICapture.SetPreviewFPS(nPreviewFPS: Double);
  1027. begin
  1028. SetPreviewFrameDelay(Round(1.0E3 * 1.0 / nPreviewFPS));
  1029. end;
  1030. function TJvAVICapture.GetPreviewFPS: Double;
  1031. begin
  1032. Result := 1.0E3 * 1.0 / FPreviewFrameDelay;
  1033. end;
  1034. procedure TJvAVICapture.SetPreviewing(nPreviewing: Boolean);
  1035. begin
  1036. if (not nPreviewing) and Previewing then
  1037. StopPreview;
  1038. if nPreviewing and (not Previewing) then
  1039. StartPreview;
  1040. end;
  1041. procedure TJvAVICapture.SetFileName(nFileName: TFileName);
  1042. begin
  1043. if FHWnd <> 0 then
  1044. begin
  1045. FFileName := nFileName;
  1046. // change the filename
  1047. capFileSetCaptureFile(FHWnd, PChar(nFileName));
  1048. end;
  1049. end;
  1050. function TJvAVICapture.GetFileName: TFileName;
  1051. var
  1052. Name: array [0..MAX_PATH] of Char;
  1053. begin
  1054. if FHWnd <> 0 then
  1055. begin
  1056. // get the filename from the window
  1057. capFileGetCaptureFile(FHWnd, Name, SizeOf(Name));
  1058. FFileName := Name;
  1059. end;
  1060. Result := FFileName;
  1061. end;
  1062. function TJvAVICapture.GetDrivers: TStrings;
  1063. begin
  1064. Result := FDrivers;
  1065. end;
  1066. procedure TJvAVICapture.SetFileSizeAlloc(nFileSizeAlloc: Cardinal);
  1067. begin
  1068. if FHWnd <> 0 then
  1069. begin
  1070. FFileSizeAlloc := nFileSizeAlloc;
  1071. capFileAlloc(FHWnd, FFileSizeAlloc);
  1072. end;
  1073. end;
  1074. procedure TJvAVICapture.SetUsedEvents(nUsedEvents: TJvUsedEvents);
  1075. begin
  1076. FUsedEvents := nUsedEvents;
  1077. if FHWnd <> 0 then
  1078. begin
  1079. if ueError in FUsedEvents then
  1080. capSetCallbackOnError(FHWnd, @ErrorCallback)
  1081. else
  1082. capSetCallbackOnError(FHWnd, nil);
  1083. if ueStatus in FUsedEvents then
  1084. capSetCallbackOnStatus(FHWnd, @StatusCallback)
  1085. else
  1086. capSetCallbackOnStatus(FHWnd, nil);
  1087. if ueYield in FUsedEvents then
  1088. capSetCallbackOnYield(FHWnd, @YieldCallback)
  1089. else
  1090. capSetCallbackOnYield(FHWnd, nil);
  1091. if ueFrame in FUsedEvents then
  1092. capSetCallbackOnFrame(FHWnd, @FrameCallback)
  1093. else
  1094. capSetCallbackOnFrame(FHWnd, nil);
  1095. if ueVideoStream in FUsedEvents then
  1096. capSetCallbackOnVideoStream(FHWnd, @VideoStreamCallback)
  1097. else
  1098. capSetCallbackOnVideoStream(FHWnd, nil);
  1099. if ueWaveStream in FUsedEvents then
  1100. capSetCallbackOnWaveStream(FHWnd, @WaveStreamCallback)
  1101. else
  1102. capSetCallbackOnWaveStream(FHWnd, nil);
  1103. if ueCapControl in FUsedEvents then
  1104. capSetCallbackOnCapControl(FHWnd, @CapControlCallback)
  1105. else
  1106. capSetCallbackOnCapControl(FHWnd, nil);
  1107. end;
  1108. end;
  1109. procedure TJvAVICapture.SetOverlaying(nOverlaying: Boolean);
  1110. begin
  1111. if not nOverlaying then
  1112. begin
  1113. if Overlaying then
  1114. StopOverlay;
  1115. end
  1116. else
  1117. if not Overlaying then
  1118. StartOverlay;
  1119. end;
  1120. function TJvAVICapture.GetDriverName: string;
  1121. var
  1122. Name: array [0..MAX_PATH] of Char;
  1123. begin
  1124. if FHWnd <> 0 then
  1125. begin
  1126. capDriverGetName(FHWnd, Name, SizeOf(Name));
  1127. Result := Name;
  1128. end
  1129. else
  1130. Result := RsNotConnected;
  1131. end;
  1132. function TJvAVICapture.GetDriverVersion: string;
  1133. var
  1134. Version: array [0..MAX_PATH] of Char;
  1135. begin
  1136. if FHWnd <> 0 then
  1137. begin
  1138. capDriverGetVersion(FHWnd, Version, SizeOf(Version));
  1139. Result := Version;
  1140. end
  1141. else
  1142. Result := RsNotConnected;
  1143. end;
  1144. procedure TJvAVICapture.SetScrollPos(nScrollPos: TJvScrollPos);
  1145. var
  1146. TmpPoint: TPoint;
  1147. begin
  1148. if FHWnd <> 0 then
  1149. begin
  1150. FScrollPos := nScrollPos;
  1151. TmpPoint.X := FScrollPos.Left;
  1152. TmpPoint.Y := FScrollPos.Top;
  1153. capSetScrollPos(FHWnd, @TmpPoint);
  1154. end;
  1155. end;
  1156. procedure TJvAVICapture.SetMCIDevice(nMCIDevice: string);
  1157. begin
  1158. if FHWnd <> 0 then
  1159. capSetMCIDeviceName(FHWnd, PChar(nMCIDevice));
  1160. end;
  1161. function TJvAVICapture.GetMCIDevice: string;
  1162. var
  1163. Name: array [0..MAX_PATH] of Char;
  1164. begin
  1165. if FHWnd <> 0 then
  1166. begin
  1167. capGetMCIDeviceName(FHWnd, Name, SizeOf(Name));
  1168. Result := Name;
  1169. end
  1170. else
  1171. Result := RsNotConnected;
  1172. end;
  1173. procedure TJvAVICapture.SetDriverIndex(nIndex: TJvDriverIndex);
  1174. begin
  1175. if Connect(nIndex) then
  1176. FDriverIndex := nIndex;
  1177. end;

Large files files are truncated, but you can click here to view the full file