EDN Admin
Well-known member
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; private <span style="color:Blue; void button3_Click(<span style="color:Blue; object sender, EventArgs e)
{
button3.Enabled = <span style="color:Blue; false;
button1.Enabled = <span style="color:Blue; true;
progressBar1.Value = 0;
label10.Text = <span style="color:#A31515; "00:00:00";
processHasStop = <span style="color:Blue; true;
timer1.Stop();
label1.Visible = <span style="color:Blue; false;
label2.Visible = <span style="color:Blue; false;
label3.Visible = <span style="color:Blue; false;
label4.Visible = <span style="color:Blue; false;
label14.Visible = <span style="color:Blue; false;
label15.Visible = <span style="color:Blue; false;
DirectoryInfo dirinfo = <span style="color:Blue; new DirectoryInfo(subDirectoryName);
<span style="color:Blue; foreach (FileInfo file <span style="color:Blue; in dirinfo.GetFiles())
{
file.Delete();
}
<span style="color:Blue; foreach (DirectoryInfo dir <span style="color:Blue; in dirinfo.GetDirectories())
{
dir.Delete(<span style="color:Blue; true);
}
Directory.Delete(subDirectoryName, <span style="color:Blue; true);
}
[/code]
<br/>
Thats what i did in Form1 in the button3 click event wich is the cancel button.
Now this is the button1 click event that start the process and thr start() function:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; private <span style="color:Blue; void button1_Click(<span style="color:Blue; object sender, EventArgs e)
{
<span style="color:Blue; if (secondPass == <span style="color:Blue; true)
{
Start(<span style="color:Blue; true);
}
Start(<span style="color:Blue; false);
}
<span style="color:Blue; private <span style="color:Blue; void Start(<span style="color:Blue; bool secondpass)
{
SetPicture(-1);
<span style="color:Blue; if (Directory.Exists(_outputDir) && secondpass == <span style="color:Blue; false)
{
}
<span style="color:Blue; else
{
Directory.CreateDirectory(_outputDir);
}
button3.Enabled = <span style="color:Blue; true;
<span style="color:Blue; string subDirectoryName = _outputDir + "\" + averagesListTextFileDirectory;
Directory.CreateDirectory(subDirectoryName);
f = <span style="color:Blue; new WmvAdapter(_videoFile,
Path.Combine(subDirectoryName));
<span style="color:Blue; if (f.codecismissing == <span style="color:Blue; true)
{
button3.Enabled = <span style="color:Blue; false;
<span style="color:Blue; return;
}
<span style="color:Blue; else
{
button3.Enabled = <span style="color:Blue; true;
}
f.Secondpass = secondpass;
f.FramesToSave = _fts;
f.FrameCountAvailable += <span style="color:Blue; new WmvAdapter.FrameCountEventHandler(f_FrameCountAvailable);
f.StatusChanged += <span style="color:Blue; new WmvAdapter.EventHandler(f_StatusChanged);
f.ProgressChanged += <span style="color:Blue; new WmvAdapter.ProgressEventHandler(f_ProgressChanged);
<span style="color:Blue; this.Text = <span style="color:#A31515; "Processing Please Wait...";
label5.Visible = <span style="color:Blue; true;
pictureBox1.Image = Lightnings_Extractor.Properties.Resources.Weather_Michmoret;
Hrs = 0; <span style="color:Green; //number of hours
Min = 0; <span style="color:Green; //number of Minutes
Sec = 0; <span style="color:Green; //number of Sec
timeElapsed = 0;
label10.Text = <span style="color:#A31515; "00:00:00";
label11.Visible = <span style="color:Blue; false;
label12.Visible = <span style="color:Blue; false;
label9.Visible = <span style="color:Blue; false;
label8.Visible = <span style="color:Blue; false;
<span style="color:Blue; this.button1.Enabled = <span style="color:Blue; false;
myTrackPanelss1.trackBar1.Enabled = <span style="color:Blue; false;
<span style="color:Blue; this.checkBox2.Enabled = <span style="color:Blue; false;
<span style="color:Blue; this.checkBox1.Enabled = <span style="color:Blue; false;
numericUpDown1.Enabled = <span style="color:Blue; false;
timer1.Start();
<span style="color:Green; //this.Enabled = false;
label2.Text = <span style="color:#A31515; "";
label1.Visible = <span style="color:Blue; true;
label2.Visible = <span style="color:Blue; true;
label3.Visible = <span style="color:Blue; true;
label4.Visible = <span style="color:Blue; true;
f.Start();
}
[/code]
When i click the cancel button the progressBar1 is keep moving like the process is still running.
Now start() in start() i have f.start
f is an instance of WmvAdapter.cs :
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; using System;
<span style="color:Blue; using System.Diagnostics;
<span style="color:Blue; using System.Drawing;
<span style="color:Blue; using System.Drawing.Imaging;
<span style="color:Blue; using System.IO;
<span style="color:Blue; using System.Runtime.InteropServices;
<span style="color:Blue; using DirectShowLib;
<span style="color:Blue; using System.Collections.Generic;
<span style="color:Blue; using Extracting_Frames;
<span style="color:Blue; using System.Windows.Forms;
<span style="color:Blue; namespace Polkan.DataSource
{
<span style="color:Blue; internal <span style="color:Blue; class WmvAdapter : ISampleGrabberCB, IDisposable
{
<span style="color:Blue; #region Fields_Properties_and_Events
<span style="color:Blue; public <span style="color:Blue; bool codecismissing = <span style="color:Blue; false;
<span style="color:Blue; private IFilterGraph2 _filterGraph;
<span style="color:Blue; private IMediaControl _mediaCtrl;
<span style="color:Blue; private IMediaEvent _mediaEvent;
<span style="color:Blue; private <span style="color:Blue; int _width;
<span style="color:Blue; private <span style="color:Blue; int _height;
<span style="color:Blue; private <span style="color:Blue; readonly <span style="color:Blue; string _outFolder;
<span style="color:Blue; private <span style="color:Blue; int _frameId;
<span style="color:Green; //better use a custom EventHandler that passes the results of the action to the subscriber.
<span style="color:Blue; public <span style="color:Blue; delegate <span style="color:Blue; void EventHandler(<span style="color:Blue; object sender, EventArgs e);
<span style="color:Blue; public <span style="color:Blue; event EventHandler StatusChanged;
<span style="color:Blue; public <span style="color:Blue; delegate <span style="color:Blue; void FrameCountEventHandler(<span style="color:Blue; object sender, FrameCountEventArgs e);
<span style="color:Blue; public <span style="color:Blue; event FrameCountEventHandler FrameCountAvailable;
<span style="color:Blue; public <span style="color:Blue; delegate <span style="color:Blue; void ProgressEventHandler(<span style="color:Blue; object sender, ProgressEventArgs e);
<span style="color:Blue; public <span style="color:Blue; event ProgressEventHandler ProgressChanged;
<span style="color:Blue; private IMediaSeeking _mSeek;
<span style="color:Blue; private <span style="color:Blue; long _duration = 0;
<span style="color:Blue; private <span style="color:Blue; long _avgFrameTime = 0;
<span style="color:Green; //just save the averages to a List (not to fs)
<span style="color:Blue; public List<<span style="color:Blue; double> AveragesList { <span style="color:Blue; get; <span style="color:Blue; set; }
<span style="color:Blue; public <span style="color:Blue; bool Secondpass { <span style="color:Blue; get; <span style="color:Blue; set; }
<span style="color:Blue; public List<<span style="color:Blue; int> FramesToSave { <span style="color:Blue; get; <span style="color:Blue; set; }
<span style="color:Blue; #endregion
<span style="color:Blue; #region Constructors and Destructors
<span style="color:Blue; public WmvAdapter(<span style="color:Blue; string file, <span style="color:Blue; string outFolder)
{
_outFolder = outFolder;
<span style="color:Blue; try
{
SetupGraph(file);
}
<span style="color:Blue; catch
{
Dispose();
MessageBox.Show(<span style="color:#A31515; "A codec is required to load this video file. Please use http://www.headbands.com/gspot/ or search the web for the correct codec");
codecismissing = <span style="color:Blue; true;
}
}
~WmvAdapter()
{
CloseInterfaces();
}
<span style="color:Blue; #endregion
<span style="color:Blue; public <span style="color:Blue; void Dispose()
{
CloseInterfaces();
}
<span style="color:Blue; public <span style="color:Blue; void Start()
{
EstimateFrameCount();
<span style="color:Blue; int hr = _mediaCtrl.Run();
WaitUntilDone();
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; public <span style="color:Blue; void WaitUntilDone()
{
<span style="color:Blue; int hr;
<span style="color:Blue; const <span style="color:Blue; int eAbort = <span style="color:Blue; unchecked((<span style="color:Blue; int)0x80004004);
<span style="color:Blue; do
{
System.Windows.Forms.Application.DoEvents();
EventCode evCode;
hr = _mediaEvent.WaitForCompletion(100, <span style="color:Blue; out evCode);
} <span style="color:Blue; while (hr == eAbort);
DsError.ThrowExceptionForHR(hr);
OnStatusChanged();
}
<span style="color:Green; //Edit: added events
<span style="color:Blue; protected <span style="color:Blue; virtual <span style="color:Blue; void OnStatusChanged()
{
<span style="color:Blue; if (StatusChanged != <span style="color:Blue; null)
StatusChanged(<span style="color:Blue; this, <span style="color:Blue; new EventArgs());
}
<span style="color:Blue; protected <span style="color:Blue; virtual <span style="color:Blue; void OnFrameCountAvailable(<span style="color:Blue; long frameCount)
{
<span style="color:Blue; if (FrameCountAvailable != <span style="color:Blue; null)
FrameCountAvailable(<span style="color:Blue; this, <span style="color:Blue; new FrameCountEventArgs() { FrameCount = frameCount });
}
<span style="color:Blue; protected <span style="color:Blue; virtual <span style="color:Blue; void OnProgressChanged(<span style="color:Blue; int frameID)
{
<span style="color:Blue; if (ProgressChanged != <span style="color:Blue; null)
ProgressChanged(<span style="color:Blue; this, <span style="color:Blue; new ProgressEventArgs() { FrameID = frameID });
}
<span style="color:Gray; /// <span style="color:Gray; <summary><span style="color:Green; build the capture graph for grabber. </summary>
<span style="color:Blue; private <span style="color:Blue; void SetupGraph(<span style="color:Blue; string file)
{
ISampleGrabber sampGrabber = <span style="color:Blue; null;
IBaseFilter capFilter = <span style="color:Blue; null;
IBaseFilter nullrenderer = <span style="color:Blue; null;
_filterGraph = (IFilterGraph2)<span style="color:Blue; new FilterGraph();
_mediaCtrl = (IMediaControl)_filterGraph;
_mediaEvent = (IMediaEvent)_filterGraph;
_mSeek = (IMediaSeeking)_filterGraph;
<span style="color:Blue; var mediaFilt = (IMediaFilter)_filterGraph;
<span style="color:Blue; try
{
<span style="color:Green; // Add the video source
<span style="color:Blue; int hr = _filterGraph.AddSourceFilter(file, <span style="color:#A31515; "Ds.NET FileFilter", <span style="color:Blue; out capFilter);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Get the SampleGrabber interface
sampGrabber = <span style="color:Blue; new SampleGrabber() <span style="color:Blue; as ISampleGrabber;
<span style="color:Blue; var baseGrabFlt = sampGrabber <span style="color:Blue; as IBaseFilter;
ConfigureSampleGrabber(sampGrabber);
<span style="color:Green; // Add the frame grabber to the graph
hr = _filterGraph.AddFilter(baseGrabFlt, <span style="color:#A31515; "Ds.NET Grabber");
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // ---------------------------------
<span style="color:Green; // Connect the file filter to the sample grabber
<span style="color:Green; // Hopefully this will be the video pin, we could check by reading its mediatype
IPin iPinOut = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0);
<span style="color:Green; // Get the input pin from the sample grabber
IPin iPinIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);
hr = _filterGraph.Connect(iPinOut, iPinIn);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Add the null renderer to the graph
nullrenderer = <span style="color:Blue; new NullRenderer() <span style="color:Blue; as IBaseFilter;
hr = _filterGraph.AddFilter(nullrenderer, <span style="color:#A31515; "Null renderer");
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // ---------------------------------
<span style="color:Green; // Connect the sample grabber to the null renderer
iPinOut = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0);
iPinIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0);
hr = _filterGraph.Connect(iPinOut, iPinIn);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Turn off the clock. This causes the frames to be sent
<span style="color:Green; // thru the graph as fast as possible
hr = mediaFilt.SetSyncSource(<span style="color:Blue; null);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Read and cache the image sizes
SaveSizeInfo(sampGrabber);
<span style="color:Green; //Edit: get the duration
hr = _mSeek.GetDuration(<span style="color:Blue; out _duration);
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; finally
{
<span style="color:Blue; if (capFilter != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(capFilter);
}
<span style="color:Blue; if (sampGrabber != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(sampGrabber);
}
<span style="color:Blue; if (nullrenderer != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(nullrenderer);
}
GC.Collect();
}
}
<span style="color:Blue; private <span style="color:Blue; void EstimateFrameCount()
{
<span style="color:Blue; try
{
<span style="color:Green; //1sec / averageFrameTime
<span style="color:Blue; double fr = 10000000.0 / _avgFrameTime;
<span style="color:Blue; double frameCount = fr * (_duration / 10000000.0);
OnFrameCountAvailable((<span style="color:Blue; long)frameCount);
}
<span style="color:Blue; catch
{
}
}
<span style="color:Blue; public <span style="color:Blue; double framesCounts()
{
<span style="color:Blue; double fr = 10000000.0 / _avgFrameTime;
<span style="color:Blue; double frameCount = fr * (_duration / 10000000.0);
<span style="color:Blue; return frameCount;
}
<span style="color:Blue; private <span style="color:Blue; void SaveSizeInfo(ISampleGrabber sampGrabber)
{
<span style="color:Green; // Get the media type from the SampleGrabber
<span style="color:Blue; var media = <span style="color:Blue; new AMMediaType();
<span style="color:Blue; int hr = sampGrabber.GetConnectedMediaType(media);
DsError.ThrowExceptionForHR(hr);
<span style="color:Blue; if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
{
<span style="color:Blue; throw <span style="color:Blue; new NotSupportedException(<span style="color:#A31515; "Unknown Grabber Media Format");
}
<span style="color:Green; // Grab the size info
<span style="color:Blue; var videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, <span style="color:Blue; typeof(VideoInfoHeader));
_width = videoInfoHeader.BmiHeader.Width;
_height = videoInfoHeader.BmiHeader.Height;
<span style="color:Green; //Edit: get framerate
_avgFrameTime = videoInfoHeader.AvgTimePerFrame;
DsUtils.FreeAMMediaType(media);
GC.Collect();
}
<span style="color:Blue; private <span style="color:Blue; void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
{
<span style="color:Blue; var media = <span style="color:Blue; new AMMediaType
{
majorType = MediaType.Video,
subType = MediaSubType.RGB24,
formatType = FormatType.VideoInfo
};
<span style="color:Blue; int hr = sampGrabber.SetMediaType(media);
DsError.ThrowExceptionForHR(hr);
DsUtils.FreeAMMediaType(media);
GC.Collect();
hr = sampGrabber.SetCallback(<span style="color:Blue; this, 1);
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; private <span style="color:Blue; void CloseInterfaces()
{
<span style="color:Blue; try
{
<span style="color:Blue; if (_mediaCtrl != <span style="color:Blue; null)
{
_mediaCtrl.Stop();
_mediaCtrl = <span style="color:Blue; null;
}
}
<span style="color:Blue; catch (Exception ex)
{
Debug.WriteLine(ex);
}
<span style="color:Blue; if (_filterGraph != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(_filterGraph);
_filterGraph = <span style="color:Blue; null;
}
GC.Collect();
}
<span style="color:Blue; int ISampleGrabberCB.SampleCB(<span style="color:Blue; double sampleTime, IMediaSample pSample)
{
Marshal.ReleaseComObject(pSample);
<span style="color:Blue; return 0;
}
<span style="color:Blue; int ISampleGrabberCB.BufferCB(<span style="color:Blue; double sampleTime, IntPtr pBuffer, <span style="color:Blue; int bufferLen)
{
<span style="color:Blue; using (<span style="color:Blue; var bitmap = <span style="color:Blue; new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
{
<span style="color:Blue; if (!<span style="color:Blue; this.Secondpass)
{
<span style="color:Green; //get avg
<span style="color:Blue; double average = GetAveragePixelValue(bitmap);
<span style="color:Blue; if (AveragesList == <span style="color:Blue; null)
AveragesList = <span style="color:Blue; new List<<span style="color:Blue; double>();
<span style="color:Green; //save avg
AveragesList.Add(average);
}
<span style="color:Blue; else
{
<span style="color:Blue; if (FramesToSave != <span style="color:Blue; null && FramesToSave.Contains(_frameId))
{
bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
bitmap.Save(Path.Combine(_outFolder, _frameId.ToString(<span style="color:#A31515; "D6") + <span style="color:#A31515; ".bmp"));
}
}
_frameId++;
<span style="color:Green; //let only report each 100 frames for performance
<span style="color:Blue; if (_frameId % 100 == 0)
OnProgressChanged(_frameId);
}
<span style="color:Blue; return 0;
}
<span style="color:Blue; private <span style="color:Blue; unsafe <span style="color:Blue; double GetAveragePixelValue(Bitmap bmp)
{
BitmapData bmData = <span style="color:Blue; null;
<span style="color:Blue; try
{
bmData = bmp.LockBits(<span style="color:Blue; new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
<span style="color:Blue; int stride = bmData.Stride;
IntPtr scan0 = bmData.Scan0;
<span style="color:Blue; int w = bmData.Width;
<span style="color:Blue; int h = bmData.Height;
<span style="color:Blue; double sum = 0;
<span style="color:Blue; long pixels = bmp.Width * bmp.Height;
<span style="color:Blue; byte* p = (<span style="color:Blue; byte*)scan0.ToPointer();
<span style="color:Blue; for (<span style="color:Blue; int y = 0; y < h; y++)
{
p = (<span style="color:Blue; byte*)scan0.ToPointer();
p += y * stride;
<span style="color:Blue; for (<span style="color:Blue; int x = 0; x < w; x++)
{
<span style="color:Blue; double i = ((<span style="color:Blue; double)p[0] + p[1] + p[2]) / 3.0;
sum += i;
p += 3;
}
<span style="color:Green; //no offset incrementation needed when getting
<span style="color:Green; //the pointer at the start of each row
}
bmp.UnlockBits(bmData);
<span style="color:Blue; double result = sum / (<span style="color:Blue; double)pixels;
<span style="color:Blue; return result;
}
<span style="color:Blue; catch
{
<span style="color:Blue; try
{
bmp.UnlockBits(bmData);
}
<span style="color:Blue; catch
{
}
}
<span style="color:Blue; return -1;
}
}
<span style="color:Blue; public <span style="color:Blue; class FrameCountEventArgs
{
<span style="color:Blue; public <span style="color:Blue; long FrameCount { <span style="color:Blue; get; <span style="color:Blue; set; }
}
<span style="color:Blue; public <span style="color:Blue; class ProgressEventArgs
{
<span style="color:Blue; public <span style="color:Blue; int FrameID { <span style="color:Blue; get; <span style="color:Blue; set; }
}
}
[/code]
in WmvAdapter.cs i have start() and waituntilldone()
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; public <span style="color:Blue; void Start()
{
EstimateFrameCount();
<span style="color:Blue; int hr = _mediaCtrl.Run();
WaitUntilDone();
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; public <span style="color:Blue; void WaitUntilDone()
{
<span style="color:Blue; int hr;
<span style="color:Blue; const <span style="color:Blue; int eAbort = <span style="color:Blue; unchecked((<span style="color:Blue; int)0x80004004);
<span style="color:Blue; do
{
System.Windows.Forms.Application.DoEvents();
EventCode evCode;
hr = _mediaEvent.WaitForCompletion(100, <span style="color:Blue; out evCode);
} <span style="color:Blue; while (hr == eAbort);
DsError.ThrowExceptionForHR(hr);
OnStatusChanged();
}
[/code]
<br/>
In Form1 in the button3 click event the cancel button i added static bool variable: processHasStop = true;<span style="font-family:Consolas; font-size:x-small <span style="font-family:Consolas; font-size:x-small <span style="font-family:Consolas; font-size:x-small <font face="Consolas" size="2" style="font-family:Consolas; font-size:x-small
</font>
I tried in the WmvAdapter.cs in the waituntilldone() to do:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; public <span style="color:Blue; void WaitUntilDone()
{
<span style="color:Blue; int hr;
<span style="color:Blue; const <span style="color:Blue; int eAbort = <span style="color:Blue; unchecked((<span style="color:Blue; int)0x80004004);
<span style="color:Blue; do
{
<span style="color:Blue; if (Form1.processHasStop == <span style="color:Blue; true)
{
_mediaCtrl.Stop();
<span style="color:Blue; return;
}
System.Windows.Forms.Application.DoEvents();
EventCode evCode;
hr = _mediaEvent.WaitForCompletion(100, <span style="color:Blue; out evCode);
} <span style="color:Blue; while (hr == eAbort);
DsError.ThrowExceptionForHR(hr);
OnStatusChanged();
}
[/code]
<br/>
<br/>
The problem is that return; it self dosent work so i did: _mediaCtrl.Stop(); but then this _mediaCtrl.Stop(); make all the program to stuck hang on i cant click any button nothing its just hanging on.
So i wonder how can i cancel the process and return to the program so it will keep working regular ?
Thanks.
View the full article
<span style="color:Blue; private <span style="color:Blue; void button3_Click(<span style="color:Blue; object sender, EventArgs e)
{
button3.Enabled = <span style="color:Blue; false;
button1.Enabled = <span style="color:Blue; true;
progressBar1.Value = 0;
label10.Text = <span style="color:#A31515; "00:00:00";
processHasStop = <span style="color:Blue; true;
timer1.Stop();
label1.Visible = <span style="color:Blue; false;
label2.Visible = <span style="color:Blue; false;
label3.Visible = <span style="color:Blue; false;
label4.Visible = <span style="color:Blue; false;
label14.Visible = <span style="color:Blue; false;
label15.Visible = <span style="color:Blue; false;
DirectoryInfo dirinfo = <span style="color:Blue; new DirectoryInfo(subDirectoryName);
<span style="color:Blue; foreach (FileInfo file <span style="color:Blue; in dirinfo.GetFiles())
{
file.Delete();
}
<span style="color:Blue; foreach (DirectoryInfo dir <span style="color:Blue; in dirinfo.GetDirectories())
{
dir.Delete(<span style="color:Blue; true);
}
Directory.Delete(subDirectoryName, <span style="color:Blue; true);
}
[/code]
<br/>
Thats what i did in Form1 in the button3 click event wich is the cancel button.
Now this is the button1 click event that start the process and thr start() function:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; private <span style="color:Blue; void button1_Click(<span style="color:Blue; object sender, EventArgs e)
{
<span style="color:Blue; if (secondPass == <span style="color:Blue; true)
{
Start(<span style="color:Blue; true);
}
Start(<span style="color:Blue; false);
}
<span style="color:Blue; private <span style="color:Blue; void Start(<span style="color:Blue; bool secondpass)
{
SetPicture(-1);
<span style="color:Blue; if (Directory.Exists(_outputDir) && secondpass == <span style="color:Blue; false)
{
}
<span style="color:Blue; else
{
Directory.CreateDirectory(_outputDir);
}
button3.Enabled = <span style="color:Blue; true;
<span style="color:Blue; string subDirectoryName = _outputDir + "\" + averagesListTextFileDirectory;
Directory.CreateDirectory(subDirectoryName);
f = <span style="color:Blue; new WmvAdapter(_videoFile,
Path.Combine(subDirectoryName));
<span style="color:Blue; if (f.codecismissing == <span style="color:Blue; true)
{
button3.Enabled = <span style="color:Blue; false;
<span style="color:Blue; return;
}
<span style="color:Blue; else
{
button3.Enabled = <span style="color:Blue; true;
}
f.Secondpass = secondpass;
f.FramesToSave = _fts;
f.FrameCountAvailable += <span style="color:Blue; new WmvAdapter.FrameCountEventHandler(f_FrameCountAvailable);
f.StatusChanged += <span style="color:Blue; new WmvAdapter.EventHandler(f_StatusChanged);
f.ProgressChanged += <span style="color:Blue; new WmvAdapter.ProgressEventHandler(f_ProgressChanged);
<span style="color:Blue; this.Text = <span style="color:#A31515; "Processing Please Wait...";
label5.Visible = <span style="color:Blue; true;
pictureBox1.Image = Lightnings_Extractor.Properties.Resources.Weather_Michmoret;
Hrs = 0; <span style="color:Green; //number of hours
Min = 0; <span style="color:Green; //number of Minutes
Sec = 0; <span style="color:Green; //number of Sec
timeElapsed = 0;
label10.Text = <span style="color:#A31515; "00:00:00";
label11.Visible = <span style="color:Blue; false;
label12.Visible = <span style="color:Blue; false;
label9.Visible = <span style="color:Blue; false;
label8.Visible = <span style="color:Blue; false;
<span style="color:Blue; this.button1.Enabled = <span style="color:Blue; false;
myTrackPanelss1.trackBar1.Enabled = <span style="color:Blue; false;
<span style="color:Blue; this.checkBox2.Enabled = <span style="color:Blue; false;
<span style="color:Blue; this.checkBox1.Enabled = <span style="color:Blue; false;
numericUpDown1.Enabled = <span style="color:Blue; false;
timer1.Start();
<span style="color:Green; //this.Enabled = false;
label2.Text = <span style="color:#A31515; "";
label1.Visible = <span style="color:Blue; true;
label2.Visible = <span style="color:Blue; true;
label3.Visible = <span style="color:Blue; true;
label4.Visible = <span style="color:Blue; true;
f.Start();
}
[/code]
When i click the cancel button the progressBar1 is keep moving like the process is still running.
Now start() in start() i have f.start
f is an instance of WmvAdapter.cs :
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; using System;
<span style="color:Blue; using System.Diagnostics;
<span style="color:Blue; using System.Drawing;
<span style="color:Blue; using System.Drawing.Imaging;
<span style="color:Blue; using System.IO;
<span style="color:Blue; using System.Runtime.InteropServices;
<span style="color:Blue; using DirectShowLib;
<span style="color:Blue; using System.Collections.Generic;
<span style="color:Blue; using Extracting_Frames;
<span style="color:Blue; using System.Windows.Forms;
<span style="color:Blue; namespace Polkan.DataSource
{
<span style="color:Blue; internal <span style="color:Blue; class WmvAdapter : ISampleGrabberCB, IDisposable
{
<span style="color:Blue; #region Fields_Properties_and_Events
<span style="color:Blue; public <span style="color:Blue; bool codecismissing = <span style="color:Blue; false;
<span style="color:Blue; private IFilterGraph2 _filterGraph;
<span style="color:Blue; private IMediaControl _mediaCtrl;
<span style="color:Blue; private IMediaEvent _mediaEvent;
<span style="color:Blue; private <span style="color:Blue; int _width;
<span style="color:Blue; private <span style="color:Blue; int _height;
<span style="color:Blue; private <span style="color:Blue; readonly <span style="color:Blue; string _outFolder;
<span style="color:Blue; private <span style="color:Blue; int _frameId;
<span style="color:Green; //better use a custom EventHandler that passes the results of the action to the subscriber.
<span style="color:Blue; public <span style="color:Blue; delegate <span style="color:Blue; void EventHandler(<span style="color:Blue; object sender, EventArgs e);
<span style="color:Blue; public <span style="color:Blue; event EventHandler StatusChanged;
<span style="color:Blue; public <span style="color:Blue; delegate <span style="color:Blue; void FrameCountEventHandler(<span style="color:Blue; object sender, FrameCountEventArgs e);
<span style="color:Blue; public <span style="color:Blue; event FrameCountEventHandler FrameCountAvailable;
<span style="color:Blue; public <span style="color:Blue; delegate <span style="color:Blue; void ProgressEventHandler(<span style="color:Blue; object sender, ProgressEventArgs e);
<span style="color:Blue; public <span style="color:Blue; event ProgressEventHandler ProgressChanged;
<span style="color:Blue; private IMediaSeeking _mSeek;
<span style="color:Blue; private <span style="color:Blue; long _duration = 0;
<span style="color:Blue; private <span style="color:Blue; long _avgFrameTime = 0;
<span style="color:Green; //just save the averages to a List (not to fs)
<span style="color:Blue; public List<<span style="color:Blue; double> AveragesList { <span style="color:Blue; get; <span style="color:Blue; set; }
<span style="color:Blue; public <span style="color:Blue; bool Secondpass { <span style="color:Blue; get; <span style="color:Blue; set; }
<span style="color:Blue; public List<<span style="color:Blue; int> FramesToSave { <span style="color:Blue; get; <span style="color:Blue; set; }
<span style="color:Blue; #endregion
<span style="color:Blue; #region Constructors and Destructors
<span style="color:Blue; public WmvAdapter(<span style="color:Blue; string file, <span style="color:Blue; string outFolder)
{
_outFolder = outFolder;
<span style="color:Blue; try
{
SetupGraph(file);
}
<span style="color:Blue; catch
{
Dispose();
MessageBox.Show(<span style="color:#A31515; "A codec is required to load this video file. Please use http://www.headbands.com/gspot/ or search the web for the correct codec");
codecismissing = <span style="color:Blue; true;
}
}
~WmvAdapter()
{
CloseInterfaces();
}
<span style="color:Blue; #endregion
<span style="color:Blue; public <span style="color:Blue; void Dispose()
{
CloseInterfaces();
}
<span style="color:Blue; public <span style="color:Blue; void Start()
{
EstimateFrameCount();
<span style="color:Blue; int hr = _mediaCtrl.Run();
WaitUntilDone();
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; public <span style="color:Blue; void WaitUntilDone()
{
<span style="color:Blue; int hr;
<span style="color:Blue; const <span style="color:Blue; int eAbort = <span style="color:Blue; unchecked((<span style="color:Blue; int)0x80004004);
<span style="color:Blue; do
{
System.Windows.Forms.Application.DoEvents();
EventCode evCode;
hr = _mediaEvent.WaitForCompletion(100, <span style="color:Blue; out evCode);
} <span style="color:Blue; while (hr == eAbort);
DsError.ThrowExceptionForHR(hr);
OnStatusChanged();
}
<span style="color:Green; //Edit: added events
<span style="color:Blue; protected <span style="color:Blue; virtual <span style="color:Blue; void OnStatusChanged()
{
<span style="color:Blue; if (StatusChanged != <span style="color:Blue; null)
StatusChanged(<span style="color:Blue; this, <span style="color:Blue; new EventArgs());
}
<span style="color:Blue; protected <span style="color:Blue; virtual <span style="color:Blue; void OnFrameCountAvailable(<span style="color:Blue; long frameCount)
{
<span style="color:Blue; if (FrameCountAvailable != <span style="color:Blue; null)
FrameCountAvailable(<span style="color:Blue; this, <span style="color:Blue; new FrameCountEventArgs() { FrameCount = frameCount });
}
<span style="color:Blue; protected <span style="color:Blue; virtual <span style="color:Blue; void OnProgressChanged(<span style="color:Blue; int frameID)
{
<span style="color:Blue; if (ProgressChanged != <span style="color:Blue; null)
ProgressChanged(<span style="color:Blue; this, <span style="color:Blue; new ProgressEventArgs() { FrameID = frameID });
}
<span style="color:Gray; /// <span style="color:Gray; <summary><span style="color:Green; build the capture graph for grabber. </summary>
<span style="color:Blue; private <span style="color:Blue; void SetupGraph(<span style="color:Blue; string file)
{
ISampleGrabber sampGrabber = <span style="color:Blue; null;
IBaseFilter capFilter = <span style="color:Blue; null;
IBaseFilter nullrenderer = <span style="color:Blue; null;
_filterGraph = (IFilterGraph2)<span style="color:Blue; new FilterGraph();
_mediaCtrl = (IMediaControl)_filterGraph;
_mediaEvent = (IMediaEvent)_filterGraph;
_mSeek = (IMediaSeeking)_filterGraph;
<span style="color:Blue; var mediaFilt = (IMediaFilter)_filterGraph;
<span style="color:Blue; try
{
<span style="color:Green; // Add the video source
<span style="color:Blue; int hr = _filterGraph.AddSourceFilter(file, <span style="color:#A31515; "Ds.NET FileFilter", <span style="color:Blue; out capFilter);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Get the SampleGrabber interface
sampGrabber = <span style="color:Blue; new SampleGrabber() <span style="color:Blue; as ISampleGrabber;
<span style="color:Blue; var baseGrabFlt = sampGrabber <span style="color:Blue; as IBaseFilter;
ConfigureSampleGrabber(sampGrabber);
<span style="color:Green; // Add the frame grabber to the graph
hr = _filterGraph.AddFilter(baseGrabFlt, <span style="color:#A31515; "Ds.NET Grabber");
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // ---------------------------------
<span style="color:Green; // Connect the file filter to the sample grabber
<span style="color:Green; // Hopefully this will be the video pin, we could check by reading its mediatype
IPin iPinOut = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0);
<span style="color:Green; // Get the input pin from the sample grabber
IPin iPinIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);
hr = _filterGraph.Connect(iPinOut, iPinIn);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Add the null renderer to the graph
nullrenderer = <span style="color:Blue; new NullRenderer() <span style="color:Blue; as IBaseFilter;
hr = _filterGraph.AddFilter(nullrenderer, <span style="color:#A31515; "Null renderer");
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // ---------------------------------
<span style="color:Green; // Connect the sample grabber to the null renderer
iPinOut = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0);
iPinIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0);
hr = _filterGraph.Connect(iPinOut, iPinIn);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Turn off the clock. This causes the frames to be sent
<span style="color:Green; // thru the graph as fast as possible
hr = mediaFilt.SetSyncSource(<span style="color:Blue; null);
DsError.ThrowExceptionForHR(hr);
<span style="color:Green; // Read and cache the image sizes
SaveSizeInfo(sampGrabber);
<span style="color:Green; //Edit: get the duration
hr = _mSeek.GetDuration(<span style="color:Blue; out _duration);
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; finally
{
<span style="color:Blue; if (capFilter != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(capFilter);
}
<span style="color:Blue; if (sampGrabber != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(sampGrabber);
}
<span style="color:Blue; if (nullrenderer != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(nullrenderer);
}
GC.Collect();
}
}
<span style="color:Blue; private <span style="color:Blue; void EstimateFrameCount()
{
<span style="color:Blue; try
{
<span style="color:Green; //1sec / averageFrameTime
<span style="color:Blue; double fr = 10000000.0 / _avgFrameTime;
<span style="color:Blue; double frameCount = fr * (_duration / 10000000.0);
OnFrameCountAvailable((<span style="color:Blue; long)frameCount);
}
<span style="color:Blue; catch
{
}
}
<span style="color:Blue; public <span style="color:Blue; double framesCounts()
{
<span style="color:Blue; double fr = 10000000.0 / _avgFrameTime;
<span style="color:Blue; double frameCount = fr * (_duration / 10000000.0);
<span style="color:Blue; return frameCount;
}
<span style="color:Blue; private <span style="color:Blue; void SaveSizeInfo(ISampleGrabber sampGrabber)
{
<span style="color:Green; // Get the media type from the SampleGrabber
<span style="color:Blue; var media = <span style="color:Blue; new AMMediaType();
<span style="color:Blue; int hr = sampGrabber.GetConnectedMediaType(media);
DsError.ThrowExceptionForHR(hr);
<span style="color:Blue; if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
{
<span style="color:Blue; throw <span style="color:Blue; new NotSupportedException(<span style="color:#A31515; "Unknown Grabber Media Format");
}
<span style="color:Green; // Grab the size info
<span style="color:Blue; var videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, <span style="color:Blue; typeof(VideoInfoHeader));
_width = videoInfoHeader.BmiHeader.Width;
_height = videoInfoHeader.BmiHeader.Height;
<span style="color:Green; //Edit: get framerate
_avgFrameTime = videoInfoHeader.AvgTimePerFrame;
DsUtils.FreeAMMediaType(media);
GC.Collect();
}
<span style="color:Blue; private <span style="color:Blue; void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
{
<span style="color:Blue; var media = <span style="color:Blue; new AMMediaType
{
majorType = MediaType.Video,
subType = MediaSubType.RGB24,
formatType = FormatType.VideoInfo
};
<span style="color:Blue; int hr = sampGrabber.SetMediaType(media);
DsError.ThrowExceptionForHR(hr);
DsUtils.FreeAMMediaType(media);
GC.Collect();
hr = sampGrabber.SetCallback(<span style="color:Blue; this, 1);
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; private <span style="color:Blue; void CloseInterfaces()
{
<span style="color:Blue; try
{
<span style="color:Blue; if (_mediaCtrl != <span style="color:Blue; null)
{
_mediaCtrl.Stop();
_mediaCtrl = <span style="color:Blue; null;
}
}
<span style="color:Blue; catch (Exception ex)
{
Debug.WriteLine(ex);
}
<span style="color:Blue; if (_filterGraph != <span style="color:Blue; null)
{
Marshal.ReleaseComObject(_filterGraph);
_filterGraph = <span style="color:Blue; null;
}
GC.Collect();
}
<span style="color:Blue; int ISampleGrabberCB.SampleCB(<span style="color:Blue; double sampleTime, IMediaSample pSample)
{
Marshal.ReleaseComObject(pSample);
<span style="color:Blue; return 0;
}
<span style="color:Blue; int ISampleGrabberCB.BufferCB(<span style="color:Blue; double sampleTime, IntPtr pBuffer, <span style="color:Blue; int bufferLen)
{
<span style="color:Blue; using (<span style="color:Blue; var bitmap = <span style="color:Blue; new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
{
<span style="color:Blue; if (!<span style="color:Blue; this.Secondpass)
{
<span style="color:Green; //get avg
<span style="color:Blue; double average = GetAveragePixelValue(bitmap);
<span style="color:Blue; if (AveragesList == <span style="color:Blue; null)
AveragesList = <span style="color:Blue; new List<<span style="color:Blue; double>();
<span style="color:Green; //save avg
AveragesList.Add(average);
}
<span style="color:Blue; else
{
<span style="color:Blue; if (FramesToSave != <span style="color:Blue; null && FramesToSave.Contains(_frameId))
{
bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
bitmap.Save(Path.Combine(_outFolder, _frameId.ToString(<span style="color:#A31515; "D6") + <span style="color:#A31515; ".bmp"));
}
}
_frameId++;
<span style="color:Green; //let only report each 100 frames for performance
<span style="color:Blue; if (_frameId % 100 == 0)
OnProgressChanged(_frameId);
}
<span style="color:Blue; return 0;
}
<span style="color:Blue; private <span style="color:Blue; unsafe <span style="color:Blue; double GetAveragePixelValue(Bitmap bmp)
{
BitmapData bmData = <span style="color:Blue; null;
<span style="color:Blue; try
{
bmData = bmp.LockBits(<span style="color:Blue; new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
<span style="color:Blue; int stride = bmData.Stride;
IntPtr scan0 = bmData.Scan0;
<span style="color:Blue; int w = bmData.Width;
<span style="color:Blue; int h = bmData.Height;
<span style="color:Blue; double sum = 0;
<span style="color:Blue; long pixels = bmp.Width * bmp.Height;
<span style="color:Blue; byte* p = (<span style="color:Blue; byte*)scan0.ToPointer();
<span style="color:Blue; for (<span style="color:Blue; int y = 0; y < h; y++)
{
p = (<span style="color:Blue; byte*)scan0.ToPointer();
p += y * stride;
<span style="color:Blue; for (<span style="color:Blue; int x = 0; x < w; x++)
{
<span style="color:Blue; double i = ((<span style="color:Blue; double)p[0] + p[1] + p[2]) / 3.0;
sum += i;
p += 3;
}
<span style="color:Green; //no offset incrementation needed when getting
<span style="color:Green; //the pointer at the start of each row
}
bmp.UnlockBits(bmData);
<span style="color:Blue; double result = sum / (<span style="color:Blue; double)pixels;
<span style="color:Blue; return result;
}
<span style="color:Blue; catch
{
<span style="color:Blue; try
{
bmp.UnlockBits(bmData);
}
<span style="color:Blue; catch
{
}
}
<span style="color:Blue; return -1;
}
}
<span style="color:Blue; public <span style="color:Blue; class FrameCountEventArgs
{
<span style="color:Blue; public <span style="color:Blue; long FrameCount { <span style="color:Blue; get; <span style="color:Blue; set; }
}
<span style="color:Blue; public <span style="color:Blue; class ProgressEventArgs
{
<span style="color:Blue; public <span style="color:Blue; int FrameID { <span style="color:Blue; get; <span style="color:Blue; set; }
}
}
[/code]
in WmvAdapter.cs i have start() and waituntilldone()
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; public <span style="color:Blue; void Start()
{
EstimateFrameCount();
<span style="color:Blue; int hr = _mediaCtrl.Run();
WaitUntilDone();
DsError.ThrowExceptionForHR(hr);
}
<span style="color:Blue; public <span style="color:Blue; void WaitUntilDone()
{
<span style="color:Blue; int hr;
<span style="color:Blue; const <span style="color:Blue; int eAbort = <span style="color:Blue; unchecked((<span style="color:Blue; int)0x80004004);
<span style="color:Blue; do
{
System.Windows.Forms.Application.DoEvents();
EventCode evCode;
hr = _mediaEvent.WaitForCompletion(100, <span style="color:Blue; out evCode);
} <span style="color:Blue; while (hr == eAbort);
DsError.ThrowExceptionForHR(hr);
OnStatusChanged();
}
[/code]
<br/>
In Form1 in the button3 click event the cancel button i added static bool variable: processHasStop = true;<span style="font-family:Consolas; font-size:x-small <span style="font-family:Consolas; font-size:x-small <span style="font-family:Consolas; font-size:x-small <font face="Consolas" size="2" style="font-family:Consolas; font-size:x-small
</font>
I tried in the WmvAdapter.cs in the waituntilldone() to do:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; public <span style="color:Blue; void WaitUntilDone()
{
<span style="color:Blue; int hr;
<span style="color:Blue; const <span style="color:Blue; int eAbort = <span style="color:Blue; unchecked((<span style="color:Blue; int)0x80004004);
<span style="color:Blue; do
{
<span style="color:Blue; if (Form1.processHasStop == <span style="color:Blue; true)
{
_mediaCtrl.Stop();
<span style="color:Blue; return;
}
System.Windows.Forms.Application.DoEvents();
EventCode evCode;
hr = _mediaEvent.WaitForCompletion(100, <span style="color:Blue; out evCode);
} <span style="color:Blue; while (hr == eAbort);
DsError.ThrowExceptionForHR(hr);
OnStatusChanged();
}
[/code]
<br/>
<br/>
The problem is that return; it self dosent work so i did: _mediaCtrl.Stop(); but then this _mediaCtrl.Stop(); make all the program to stuck hang on i cant click any button nothing its just hanging on.
So i wonder how can i cancel the process and return to the program so it will keep working regular ?
Thanks.
View the full article