Tried to google for the exception on directshowlib but no success to find a solution.

The exception is on line 168:

DsError.ThrowExceptionForHR(hr);

It's in the method WaitUntilDone from line 149:

public void WaitUntilDone()
        {
            int hr;
            const int eAbort = unchecked((int)0x80004004);

            do
            {
               
                    System.Windows.Forms.Application.DoEvents();
                    EventCode evCode;
                    if (dis == true)
                    {
                        return;
                    }
                    
                    hr = _mediaEvent.WaitForCompletion(100, out evCode);
                
            }while (hr == eAbort);
            
            DsError.ThrowExceptionForHR(hr);
            OnStatusChanged();
        }

The message:

System.Runtime.InteropServices.COMException: 'The operation could not be performed because the filter is in the wrong state.'

The full exception:

System.Runtime.InteropServices.COMException
  HResult=0x80040227
  Message=The operation could not be performed because the filter is in the wrong state.
  Source=DirectShowLib-2005
  StackTrace:
   at DirectShowLib.DsError.ThrowExceptionForHR(Int32 hr)
   at Polkan.DataSource.WmvAdapter.WaitUntilDone() in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\WmvAdapter.cs:line 168
   at Polkan.DataSource.WmvAdapter.Start() in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\WmvAdapter.cs:line 144
   at Extracting_Frames.Form1.Start(Boolean secondpass) in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\Form1.cs:line 351
   at Extracting_Frames.Form1.f_StatusChanged(Object sender, EventArgs e) in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\Form1.cs:line 589
   at Polkan.DataSource.WmvAdapter.OnStatusChanged() in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\WmvAdapter.cs:line 176
   at Polkan.DataSource.WmvAdapter.WaitUntilDone() in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\WmvAdapter.cs:line 169
   at Polkan.DataSource.WmvAdapter.Start() in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\WmvAdapter.cs:line 144
   at Extracting_Frames.Form1.Start(Boolean secondpass) in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\Form1.cs:line 351
   at Extracting_Frames.Form1.button8_Click(Object sender, EventArgs e) in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\Form1.cs:line 1738
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Extracting_Frames.Program.Main() in D:\Csharp Projects\Extracting_Frames\Extracting_Frames\Extracting_Frames\Program.cs:line 18

The class code is a bit long so I put it in pastebin.com for some reason I can put in pastebin.com only private.

I will put here the class it's a bit long:

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using DirectShowLib;
using System.Collections.Generic;
using Extracting_Frames;
using System.Windows.Forms;
using WindowsFormsApplication1;
using System.Text.RegularExpressions;
using System.Linq;

namespace Polkan.DataSource
{
    internal class WmvAdapter : ISampleGrabberCB, IDisposable
    {
        #region Fields_Properties_and_Events

        struct DirectoryStruct
        {
            public string name;
            public int lowrange;
            public int highrange;
        }
        List<DirectoryStruct> parseLightningsDirectories;
        string path_exe;
        string histograms_dat_fileName_Directory;
        public string fileName;
        public string fileNameRGB;
        bool dis = false;
        int count = 0;
        private string histograms_dat_fileName = "";
        private string histograms_dat_filenameRGB = "";
        private IFilterGraph2 _filterGraph;
        private IMediaControl _mediaCtrl;
        private IMediaEvent _mediaEvent;
        private int _width;
        private int _height;
        private readonly string _outFolder;
        private readonly string _allFilesOutFolder;
        private int _frameId;
        //better use a custom EventHandler that passes the results of the action to the subscriber.
        public delegate void EventHandler(object sender, EventArgs e);
        public event EventHandler StatusChanged;

        public delegate void FrameCountEventHandler(object sender, FrameCountEventArgs e);
        public event FrameCountEventHandler FrameCountAvailable;

        public delegate void ProgressEventHandler(object sender, ProgressEventArgs e);
        public event ProgressEventHandler ProgressChanged;

        public IMediaSeeking _mSeek;
        public long _duration = 0;
        private long _avgFrameTime = 0;
        private string histogramDatOutputFile;
        private string combinedDatDir;
       
        //just save the averages to a List (not to fs)
        public List<double> AveragesList { get; set; }

        public List<long> histogramValueListR;
        public List<long> histogramValueListG;
        public List<long> histogramValueListB;
        public List<long> histogramValueList;

        public bool Secondpass { get; set; }
        
        public List<int> FramesToSave { get; set; }
        public List<string> LightningsDirectories;
        StreamWriter w;

        #endregion

        #region Constructors and Destructors

        public WmvAdapter(string file, string outFolder)
        {
            histogramDatOutputFile = Form1._outputDir;
            path_exe = path_exe = Path.GetDirectoryName(Application.LocalUserAppDataPath);
            histograms_dat_fileName = "histogramValues.dat";
            histograms_dat_filenameRGB = "histogramValuesRGB.dat";
            //histograms_dat_fileName_Directory = path_exe + "\\" + "dat file";
            histograms_dat_fileName_Directory = Path.Combine(path_exe, "dat file", Path.GetFileName(file));
            fileName = histograms_dat_fileName_Directory + "\\" + histograms_dat_fileName;
            fileNameRGB = histograms_dat_fileName_Directory + "\\" + histograms_dat_filenameRGB;
            
            if (!Directory.Exists(histograms_dat_fileName_Directory))
            {
                Directory.CreateDirectory(histograms_dat_fileName_Directory);
                
                    //File.Create(histograms_dat_fileName_Directory + "\\" + histogramDatOutputFile); // to add options db to save this file name after creation. 
                    // and use the file name histogramDatOutputFile in Form1 from the options db to load the file name as output dir for the current histogram dat file !
                    //string d = histograms_dat_fileName_Directory + "\\" + histogramDatOutputFile;
                    //combinedDatDir = Path.Combine(histograms_dat_fileName_Directory, histogramDatOutputFile);
                    Options_DB.set_datFileOutputDir(histograms_dat_fileName_Directory);
                
            }
            else
            {
               
                    //File.Create(histograms_dat_fileName_Directory + "\\" + histogramDatOutputFile); // to add options db to save this file name after creation. 
                    // and use the file name histogramDatOutputFile in Form1 from the options db to load the file name as output dir for the current histogram dat file !
                    //string d = histograms_dat_fileName_Directory + "\\" + histogramDatOutputFile;
                    //combinedDatDir = Path.Combine(histograms_dat_fileName_Directory, histogramDatOutputFile);
                    Options_DB.set_datFileOutputDir(histograms_dat_fileName_Directory);
                
            }

            _outFolder = outFolder;
            try
            {
                SetupGraph(file);
            }
            catch(Exception err)
            {
                Dispose();
                string myer = err.ToString();
                MessageBox.Show("A codec is required to load this video file. Please use http://www.headbands.com/gspot/ or search the web for the correct codec");
            }
        }

        ~WmvAdapter()
        {
            CloseInterfaces();
        }

        #endregion

        public void Dispose()
        {
            CloseInterfaces();
        }
        
        public void Start()
        {
            if (this.Secondpass)
            {
                //w = new StreamWriter(@"i:\NumbersTest.txt");
            }
                EstimateFrameCount();
                    int hr = _mediaCtrl.Run();
                    WaitUntilDone();
                    DsError.ThrowExceptionForHR(hr);
                
        }

        public void WaitUntilDone()
        {
            int hr;
            const int eAbort = unchecked((int)0x80004004);

            do
            {
               
                    System.Windows.Forms.Application.DoEvents();
                    EventCode evCode;
                    if (dis == true)
                    {
                        return;
                    }
                    
                    hr = _mediaEvent.WaitForCompletion(100, out evCode);
                
            }while (hr == eAbort);
            
            DsError.ThrowExceptionForHR(hr);
            OnStatusChanged();
        }

        //Edit: added events
        protected virtual void OnStatusChanged()
        {
            if (StatusChanged != null)
                StatusChanged(this, new EventArgs());
        }

        protected virtual void OnFrameCountAvailable(long frameCount)
        {
            if (FrameCountAvailable != null)
                FrameCountAvailable(this, new FrameCountEventArgs() { FrameCount = frameCount });
        }

        protected virtual void OnProgressChanged(int frameID)
        {
            if (ProgressChanged != null)
                ProgressChanged(this, new ProgressEventArgs() { FrameID = frameID });
        }

        /// <summary> build the capture graph for grabber. </summary>
        private void SetupGraph(string file)
        {
            ISampleGrabber sampGrabber = null;
            IBaseFilter capFilter = null;
            IBaseFilter nullrenderer = null;

            _filterGraph = (IFilterGraph2)new FilterGraph();
            _mediaCtrl = (IMediaControl)_filterGraph;
            _mediaEvent = (IMediaEvent)_filterGraph;

            _mSeek = (IMediaSeeking)_filterGraph;

            var mediaFilt = (IMediaFilter)_filterGraph;

            try
            {
                // Add the video source
                int hr = _filterGraph.AddSourceFilter(file, "Ds.NET FileFilter", out capFilter);
                DsError.ThrowExceptionForHR(hr);

                // Get the SampleGrabber interface
                sampGrabber = new SampleGrabber() as ISampleGrabber;

                var baseGrabFlt = sampGrabber as IBaseFilter;

                ConfigureSampleGrabber(sampGrabber);

                // Add the frame grabber to the graph
                hr = _filterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
                DsError.ThrowExceptionForHR(hr);

                // ---------------------------------
                // Connect the file filter to the sample grabber

                // Hopefully this will be the video pin, we could check by reading it's mediatype
                IPin iPinOut = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0);

                // Get the input pin from the sample grabber
                IPin iPinIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);

                hr = _filterGraph.Connect(iPinOut, iPinIn);
                DsError.ThrowExceptionForHR(hr);

                // Add the null renderer to the graph
                nullrenderer = new NullRenderer() as IBaseFilter;
                hr = _filterGraph.AddFilter(nullrenderer, "Null renderer");
                DsError.ThrowExceptionForHR(hr);

                // ---------------------------------
                // 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);

                // Turn off the clock. This causes the frames to be sent
                // thru the graph as fast as possible
                hr = mediaFilt.SetSyncSource(null);
                DsError.ThrowExceptionForHR(hr);

                // Read and cache the image sizes
                SaveSizeInfo(sampGrabber);

                //Edit: get the duration
                hr = _mSeek.GetDuration(out _duration);
                DsError.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (capFilter != null)
                {
                    Marshal.ReleaseComObject(capFilter);
                }
                if (sampGrabber != null)
                {
                    Marshal.ReleaseComObject(sampGrabber);
                }
                if (nullrenderer != null)
                {
                    Marshal.ReleaseComObject(nullrenderer);
                }
                GC.Collect();
            }
        }

        private void EstimateFrameCount()
        {
            try
            {
                //1sec / averageFrameTime
                double fr = 10000000.0 / _avgFrameTime;
                double frameCount = fr * (_duration / 10000000.0);
                OnFrameCountAvailable((long)frameCount);

            }
            catch
            {

            }
        }

        public double framesCounts()
        {
            double fr = 10000000.0 / _avgFrameTime;
            double frameCount = fr * (_duration / 10000000.0);
            return frameCount;
        }

        private void SaveSizeInfo(ISampleGrabber sampGrabber)
        {
            // Get the media type from the SampleGrabber
            var media = new AMMediaType();
            int hr = sampGrabber.GetConnectedMediaType(media);
            DsError.ThrowExceptionForHR(hr);

            if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
            {
                throw new NotSupportedException("Unknown Grabber Media Format");
            }

            // Grab the size info
            var videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
            _width = videoInfoHeader.BmiHeader.Width;
            _height = videoInfoHeader.BmiHeader.Height;
            //Edit: get framerate
            _avgFrameTime = videoInfoHeader.AvgTimePerFrame;

            DsUtils.FreeAMMediaType(media);
            GC.Collect();
        }

        private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
        {
            var media = new AMMediaType
            {
                majorType = MediaType.Video,
                subType = MediaSubType.RGB24,
                formatType = FormatType.VideoInfo
            };
            int hr = sampGrabber.SetMediaType(media);
            DsError.ThrowExceptionForHR(hr);

            DsUtils.FreeAMMediaType(media);
            GC.Collect();
            hr = sampGrabber.SetCallback(this, 1);
            DsError.ThrowExceptionForHR(hr);
        }

        private void CloseInterfaces()
        {
            try
            {
                if (_mediaCtrl != null)
                {
                    _mediaCtrl.Stop();
                    _mediaCtrl = null;
                    dis = true;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }

            if (_filterGraph != null)
            {
                Marshal.ReleaseComObject(_filterGraph);
                _filterGraph = null;
            }
            GC.Collect();
        }
        int ISampleGrabberCB.SampleCB(double sampleTime, IMediaSample pSample)
        {
            Marshal.ReleaseComObject(pSample);
            return 0;
        }

        int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
        {
            
            if (Form1.ExtractAutomatic == true)
            {

                if (this.Secondpass)
                {
                    //extract ranges
                    LightningsDirectories = Form1.lightningsRegions;
                    parseLightningsDirectories = new List<DirectoryStruct>();
                    string pattern = @"\[(\d+)\D+(\d+)";
                    Regex expression = new Regex(pattern);
                    foreach (string Directory in LightningsDirectories)
                    {
                        Match match = expression.Match(Directory);
                        DirectoryStruct newrow = new DirectoryStruct();
                        newrow.name = Directory;
                        newrow.lowrange = int.Parse(match.Groups[1].Value);
                        newrow.highrange = int.Parse(match.Groups[2].Value);
                        parseLightningsDirectories.Add(newrow);
                    }
                    

                }

          using (var bitmap = new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
          {
              if (this.Secondpass)
              {
                  if (FramesToSave != null && FramesToSave.Contains(_frameId))
                  {

                      DirectoryStruct[] myrow = parseLightningsDirectories.Where(row =>
                                         (row.lowrange <= _frameId) && (row.highrange >= _frameId)).Select(row => row).ToArray();
                      bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
                      var myrows = parseLightningsDirectories.Where(row =>
                        (row.lowrange <= _frameId) && (row.highrange >= _frameId)).Select(row => row);
                      bitmap.Save(Path.Combine(_outFolder + "\\" + myrow[0].name, _frameId.ToString("D6") + ".bmp"));
                      long[] HistogramsValuesR = Form1.GetHistogramRGB(bitmap, Form1.ColorChannel.Red);
                      if (histogramValueListR == null)
                          histogramValueListR = new List<long>(256);
                      histogramValueListR.AddRange(HistogramsValuesR);

                      long[] HistogramsValuesG = Form1.GetHistogramRGB(bitmap, Form1.ColorChannel.Green);
                      if (histogramValueListG == null)
                          histogramValueListG = new List<long>(256);
                     /*This line throw out of memory exception*/   histogramValueListG.AddRange(HistogramsValuesG);
                     
                      long[] HistogramsValuesB = Form1.GetHistogramRGB(bitmap, Form1.ColorChannel.Blue);
                      if (histogramValueListB == null)
                          histogramValueListB = new List<long>(256);
                      histogramValueListB.AddRange(HistogramsValuesB);

                  }
              }
              else
              {
                  //this is the changed part
                  using (Bitmap original_bmp = new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
                  {
                      if (_frameId > 0)
                      {
                          long[] HistogramValues = Form1.GetHistogram(original_bmp);
                          if (histogramValueList == null)
                              histogramValueList = new List<long>(256);
                          histogramValueList.AddRange(HistogramValues);
                          if (Form1.extractallframes == true)
                          {
                              original_bmp.Save(Path.Combine(_outFolder + "\\", _frameId.ToString("D6") + ".bmp"));
                          }

                      }
                  }
              }
                    _frameId++;
                    //let only report each 100 frames for performance
                    if (_frameId % 100 == 0)
                        OnProgressChanged(_frameId);
                }
            }
            else
            {
                using (var bitmap = new Bitmap(_width, _height, _width * 3, PixelFormat.Format24bppRgb, pBuffer))
                {
                    if (!this.Secondpass)
                    {
                        //get avg
                        double average = GetAveragePixelValue(bitmap);

                        if (AveragesList == null)
                            AveragesList = new List<double>();
                        //save avg
                        AveragesList.Add(average);
                    }
                    else
                    {
                        if (FramesToSave != null && FramesToSave.Contains(_frameId))
                        {
                            bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);
                            bitmap.Save(Path.Combine(_outFolder, _frameId.ToString("D6") + ".bmp"));
                            using (BinaryWriter binWriter =
                    new BinaryWriter(File.Open(fileName, FileMode.Create)))
                            {
                            }
                        }                       
                    }
                    _frameId++;
                    //let only report each 100 frames for performance
                    if (_frameId % 100 == 0)
                        OnProgressChanged(_frameId);
                }
            }
                return 0;
        }


        public static Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight)
        {
            Bitmap result = new Bitmap(nWidth, nHeight);
            using (Graphics g = Graphics.FromImage((Image)result))
                g.DrawImage(b, 0, 0, nWidth, nHeight);
            return result;
        }
        private unsafe double GetAveragePixelValue(Bitmap bmp)
        {
            BitmapData bmData = null;

            try
            {
                bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

                int stride = bmData.Stride;
                IntPtr scan0 = bmData.Scan0;
                int w = bmData.Width;
                int h = bmData.Height;

                double sum = 0;
                long pixels = bmp.Width * bmp.Height;

                byte* p = (byte*)scan0.ToPointer();

                for (int y = 0; y < h; y++)
                {
                    p = (byte*)scan0.ToPointer();
                    p += y * stride;

                    for (int x = 0; x < w; x++)
                    {
                        double i = ((double)p[0] + p[1] + p[2]) / 3.0;
                        sum += i;

                        p += 3;
                    }

                    //no offset incrementation needed when getting 
                    //the pointer at the start of each row
                }

                bmp.UnlockBits(bmData);

                double result = sum / (double)pixels;

                return result;
            }
            catch
            {
                try
                {
                    bmp.UnlockBits(bmData);
                }
                catch
                {

                }
            }
            return -1;
        }
    }

    public class FrameCountEventArgs
    {
        public long FrameCount { get; set; }
    }

    public class ProgressEventArgs
    {
        public int FrameID { get; set; }
    }

    public class duration
    {
        public long durationTime { get; set; }
    }
}
1

There are 1 best solutions below

0
Roman Ryltsov On

One of the filters in the filter graph is triggering this error and forwarding it through filter graph manager. By registering the failure code and the exception, you don't see the filter which is the origin of the error.

You need to identify the source of the problem, for example, by reducing filter graph isolating to specific filter. Your customer filter implementing histogram is the likely source of the problem, for example.

The problem might also be related to changed filter graph compared to past times when things worked well. Long story short, you are interested to narrow down the source of the problem to specific filter.