BSOne.SFC/EM.Lib/ImageEn_SRC/Demos/VideoCapture/MediaFoundationFile/umain.pas

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.