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.