285 lines
8.4 KiB
Plaintext
285 lines
8.4 KiB
Plaintext
unit umain;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
|
StdCtrls, ieview, imageenview, Buttons, ComCtrls, ExtCtrls, Menus, hyieutils,
|
|
hyiedefs, imageenproc, iemmf, iexBitmaps, iesettings, iexLayers, iexRulers;
|
|
|
|
type
|
|
Tfmain = class(TForm)
|
|
ImageEnView1: TImageEnView;
|
|
Panel1: TPanel;
|
|
GroupBox1: TGroupBox;
|
|
Label1: TLabel;
|
|
SpeedButton1: TSpeedButton;
|
|
GroupBox2: TGroupBox;
|
|
Label2: TLabel;
|
|
TrackBar1: TTrackBar;
|
|
ListBox1: TListBox;
|
|
Label5: TLabel;
|
|
Button5: TButton;
|
|
Label3: TLabel;
|
|
Timer1: TTimer;
|
|
EditInputFile: TEdit;
|
|
ButtonOpenDialog: TButton;
|
|
OpenDialog1: TOpenDialog;
|
|
ButtonOpen: TButton;
|
|
Label6: TLabel;
|
|
ListBoxStreams: TListBox;
|
|
Label7: TLabel;
|
|
ScrollBarPosition: TScrollBar;
|
|
CheckBoxRenderAudio: TCheckBox;
|
|
Label4: TLabel;
|
|
Label8: TLabel;
|
|
procedure SpeedButton1Click(Sender: TObject);
|
|
procedure TrackBar1Change(Sender: TObject);
|
|
procedure Button5Click(Sender: TObject);
|
|
procedure ImageEnView1MediaFoundationNotify(Sender, MediaFoundationObject: TObject; NotifyType: TIEMediaFountationNotifyType);
|
|
procedure Timer1Timer(Sender: TObject);
|
|
procedure ButtonOpenDialogClick(Sender: TObject);
|
|
procedure ButtonOpenClick(Sender: TObject);
|
|
procedure ListBoxStreamsClick(Sender: TObject);
|
|
procedure ScrollBarPositionChange(Sender: TObject);
|
|
private
|
|
{ Private declarations }
|
|
public
|
|
{ Public declarations }
|
|
end;
|
|
|
|
var
|
|
fmain: Tfmain;
|
|
|
|
implementation
|
|
|
|
|
|
|
|
{$R *.DFM}
|
|
{$R WindowsTheme.res}
|
|
|
|
|
|
// Select a file to open
|
|
procedure Tfmain.ButtonOpenDialogClick(Sender: TObject);
|
|
begin
|
|
if OpenDialog1.Execute() then
|
|
EditInputFile.Text := OpenDialog1.FileName;
|
|
end;
|
|
|
|
|
|
// Open selected file
|
|
procedure Tfmain.ButtonOpenClick(Sender: TObject);
|
|
var
|
|
i: integer;
|
|
mediaType: TIEDictionary;
|
|
begin
|
|
// for test purposes only!!
|
|
if EditInputFile.Text = '' then
|
|
EditInputFile.Text := 'C:\immagini\video\NASA Robot.mp4';
|
|
|
|
ImageEnView1.IO.MediaFoundationSourceReader.SetFileInput(EditInputFile.Text);
|
|
|
|
// Fill streams listbox
|
|
ListBoxStreams.Clear();
|
|
with ImageEnView1.IO.MediaFoundationSourceReader do
|
|
begin
|
|
for i := 0 to StreamCount - 1 do
|
|
begin
|
|
mediaType := GetMediaType(i, 0);
|
|
ListBoxStreams.Items.Add(Format('%s', [mediaType.GetString(IEMAJORTYPE_DICT_KEY)]));
|
|
end;
|
|
end;
|
|
|
|
// Select first video stream
|
|
ListBoxStreams.ItemIndex := ImageEnView1.IO.MediaFoundationSourceReader.IndexOfFirstStream(mmf_VIDEO_STREAM);
|
|
ListBoxStreamsClick(self);
|
|
end;
|
|
|
|
|
|
// Select a stream
|
|
procedure Tfmain.ListBoxStreamsClick(Sender: TObject);
|
|
var
|
|
i: integer;
|
|
mediaType: TIEDictionary;
|
|
begin
|
|
if ListBoxStreams.ItemIndex > -1 then
|
|
begin
|
|
// Fill supported formats listbox for the selected stream
|
|
ListBox1.Clear();
|
|
with ImageEnView1.IO.MediaFoundationSourceReader do
|
|
begin
|
|
for i := 0 to GetMediaTypesCount(ListBoxStreams.ItemIndex) - 1 do
|
|
begin
|
|
mediaType := GetMediaType(ListBoxStreams.ItemIndex, i);
|
|
if mediaType.GetString(IEMAJORTYPE_DICT_KEY) = mmf_VIDEO_STREAM then
|
|
begin
|
|
ListBox1.Items.Add(Format('%d x %d %.1f fps %s', [
|
|
mediaType.GetInteger(IEFRAMEWIDTH_DICT_KEY), // width
|
|
mediaType.GetInteger(IEFRAMEHEIGHT_DICT_KEY), // height
|
|
mediaType.GetDouble(IEFRAMERATE_DICT_KEY), // default frame rate
|
|
mediaType.GetString(IESUBTYPE_DICT_KEY) // subtype = color space
|
|
]));
|
|
end
|
|
else
|
|
begin
|
|
ListBox1.Items.Add(Format('%s', [
|
|
mediaType.GetString(IESUBTYPE_DICT_KEY) // subtype
|
|
]));
|
|
end;
|
|
end;
|
|
end;
|
|
ListBox1.ItemIndex := 0;
|
|
end;
|
|
|
|
SpeedButton1.Enabled := true;
|
|
end;
|
|
|
|
|
|
// Capture button
|
|
procedure Tfmain.SpeedButton1Click(Sender: TObject);
|
|
var
|
|
i: integer;
|
|
audioStreamIndex: DWORD;
|
|
begin
|
|
if SpeedButton1.Down then
|
|
begin
|
|
// start capture
|
|
ListBox1.Enabled := false;
|
|
ListBoxStreams.Enabled := false;
|
|
ButtonOpen.Enabled := false;
|
|
ScrollBarPosition.Position := 0;
|
|
CheckBoxRenderAudio.Enabled := false;
|
|
|
|
// select streams selected by ListBoxStreams
|
|
for i := 0 to ListBoxStreams.Items.Count - 1 do
|
|
ImageEnView1.IO.MediaFoundationSourceReader.SetSelectedStreams(i, ListBoxStreams.Selected[i]);
|
|
|
|
// select media type
|
|
ImageEnView1.IO.MediaFoundationSourceReader.SelectMediaType(ListBoxStreams.ItemIndex, ListBox1.ItemIndex);
|
|
|
|
// Render Audio? (warn: can be out of synch, this is a grabber not a media-player!)
|
|
if CheckBoxRenderAudio.Checked then
|
|
begin
|
|
audioStreamIndex := ImageEnView1.IO.MediaFoundationSourceReader.IndexOfFirstStream(mmf_AUDIO_STREAM);
|
|
ImageEnView1.IO.MediaFoundationSourceReader.SetSelectedStreams(audioStreamIndex, true);
|
|
ImageEnView1.IO.MediaFoundationSourceReader.SetMediaTypeAudio(audioStreamIndex, mmf_AudioFormat_PCM);
|
|
ImageEnView1.IO.MediaFoundationSourceReader.PushNotifyReceiver( TIEMediaFoundationAudioRenderer.Create(audioStreamIndex) );
|
|
end;
|
|
|
|
// start capture
|
|
ImageEnView1.IO.MediaFoundationSourceReader.StartCapture();
|
|
|
|
// get actual video format (ie MJPEG may be converted to YUY2)
|
|
with ImageEnView1.IO.MediaFoundationSourceReader.GetCurrentMediaType(ListBoxStreams.ItemIndex) do
|
|
begin
|
|
if GetString(IEMAJORTYPE_DICT_KEY) = mmf_VIDEO_STREAM then
|
|
Label4.Caption := Format('Actual video format: %d x %d %.1f fps %s', [
|
|
GetInteger(IEFRAMEWIDTH_DICT_KEY), // width
|
|
GetInteger(IEFRAMEHEIGHT_DICT_KEY), // height
|
|
GetDouble(IEFRAMERATE_DICT_KEY), // frame rate
|
|
GetString(IESUBTYPE_DICT_KEY) // subtype = color space
|
|
]);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// stop capture
|
|
ImageEnView1.IO.MediaFoundationSourceReader.StopCapture();
|
|
if CheckBoxRenderAudio.Checked then
|
|
ImageEnView1.IO.MediaFoundationSourceReader.PopNotifyReceiver(); // remove audio renderer
|
|
|
|
ButtonOpen.Enabled := true;
|
|
ListBoxStreams.Enabled := true;
|
|
ListBox1.Enabled := true;
|
|
Label4.Caption := '';
|
|
CheckBoxRenderAudio.Enabled := true;
|
|
end;
|
|
end;
|
|
|
|
|
|
// Save image
|
|
procedure Tfmain.Button5Click(Sender: TObject);
|
|
begin
|
|
ImageEnView1.IO.SaveToFile(ImageEnView1.IO.ExecuteSaveDialog('', '', false, 1, ''));
|
|
end;
|
|
|
|
|
|
// Zoom
|
|
procedure Tfmain.TrackBar1Change(Sender: TObject);
|
|
begin
|
|
ImageEnView1.Zoom := TrackBar1.Position;
|
|
end;
|
|
|
|
|
|
// Timer1 and FPS are necessary just to calculate effective FPS
|
|
var
|
|
FPS: integer = 0;
|
|
|
|
|
|
// frame received
|
|
procedure Tfmain.ImageEnView1MediaFoundationNotify(Sender, MediaFoundationObject: TObject; NotifyType: TIEMediaFountationNotifyType);
|
|
var
|
|
msg: string;
|
|
grabber: TIEMediaFoundationSourceReader;
|
|
sample: TIEMFReceivedSample;
|
|
begin
|
|
case NotifyType of
|
|
|
|
iemfnFRAME:
|
|
begin
|
|
grabber := MediaFoundationObject as TIEMediaFoundationSourceReader;
|
|
sample := grabber.GetNextSample();
|
|
|
|
try
|
|
if sample.StreamType = mmf_VIDEO_STREAM then
|
|
begin
|
|
// process Video sample
|
|
sample.DecodeSample(ImageEnView1.IEBitmap);
|
|
|
|
// draw timings
|
|
msg := Format('%s / %s', [IEMediaFoundationTimeToStr(sample.TimeStamp), IEMediaFoundationTimeToStr(grabber.Duration)]);
|
|
ImageEnView1.IEBitmap.IECanvas.Brush.Style := bsSolid;
|
|
ImageEnView1.IEBitmap.IECanvas.Brush.Color := clYellow;
|
|
ImageEnView1.IEBitmap.IECanvas.Font.Color := clBlue;
|
|
ImageEnView1.IEBitmap.IECanvas.Font.Name := 'Arial';
|
|
ImageEnView1.IEBitmap.IECanvas.Font.Height := 20;
|
|
ImageEnView1.IEBitmap.IECanvas.TextOut(0, ImageEnView1.IEBitmap.Height - 20, msg);
|
|
|
|
ImageEnView1.Update();
|
|
inc(FPS);
|
|
end;
|
|
finally
|
|
sample.Free();
|
|
end;
|
|
end;
|
|
|
|
iemfnENDOFSTREAM:
|
|
begin
|
|
// End of stream, stop capture
|
|
SpeedButton1.Down := false;
|
|
SpeedButton1Click(self);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
// just to count FPS
|
|
procedure Tfmain.Timer1Timer(Sender: TObject);
|
|
begin
|
|
Label3.Caption := Format('%d FPS', [FPS]);
|
|
FPS := 0;
|
|
end;
|
|
|
|
|
|
// set new position
|
|
procedure Tfmain.ScrollBarPositionChange(Sender: TObject);
|
|
var
|
|
duration: int64;
|
|
begin
|
|
duration := ImageEnView1.IO.MediaFoundationSourceReader.Duration;
|
|
ImageEnView1.IO.MediaFoundationSourceReader.SetPosition( trunc(duration / ScrollBarPosition.Max * ScrollBarPosition.Position) );
|
|
end;
|
|
|
|
|
|
end.
|