QueryInterface error with E_NOINTERFACE in C #

Hello members

I am new to C # programming. I am developing a basic application for streaming and recording photos. After the user has done everything possible, I will display it on the overlay using the concept of mixing the VMR9 bitmap.

What I've done?

  • I am using C # direct show library from here
  • First I get all the necessary filters. Find the included capture device. A Render stream is called with a source filter and vmr9 to output PREVIEW. Source filter, sample capture and zero render for STILL PIN.
  • I have three menu buttons -> do more, show overlay and hide overlay.
  • I use the sample raster mixer provided in this library.
  • Each time the user clicks the Take Still button, the image will be saved on the desktop and will be resized to small resolution and displayed on the video image.
  • Show overlay and hide overlay calls to ShowHideBitmap (), which perform the query operation of the VMR9BitmapMixer interface from the vmr9 filter, populates the VMR9AlphaBitmap structure, and then calls the IVMRMixerBitmap9.SetAlphaBitmap function.

What problems do I encounter?

  • At the end of the recording, if I call ShowHideBitmap () through the menu item, the still image made is perfectly updated on the overlay.
  • This is another option that automatically updates the overlay as soon as a still image is saved. I am creating an event-based thread and have it wait for an update event created using EventWaitHandle. Before returning from the samplegrabber BufferCB function, I set this update event. This, in turn, continues with a waiting thread. Inside the stream, I call the ShowHideBitmap function. In this case, I get the error message as follows.

Unable to case COM object of type 'DirectShowLib.VideoMixingRenderer9' to interface type 'DirectShowLib.IVMRMixerBitmap9'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{ced175e5-1935-4820-81bd-ff6ad00c9108}' failed due to the following error: No such interface supported (Exception from HRESULT: 0X80040002 (E_NOINTERFACE)

Here is the code block of the ShowHideBitmap function

 //Declarations private static IBaseFilter vmr9 = null; private static IVMRMixerBitmap9 vmr9mixerBitmap = null; private IVMRWindowlessControl9 vmr9windowlessCtrl = null; private static void ShowHideBitmap(Boolean bEnable) { int hr = 0; VMR9AlphaBitmap alphaBmp; if (!bEnable) { if (vmr9mixerBitmap != null) { // Get current Alpha Bitmap Parameters hr = vmr9mixerBitmap.GetAlphaBitmapParameters(out alphaBmp); DsError.ThrowExceptionForHR(hr); // Disable them alphaBmp.dwFlags = VMR9AlphaBitmapFlags.Disable; // Update the Alpha Bitmap Parameters hr = vmr9mixerBitmap.UpdateAlphaBitmapParameters(ref alphaBmp); DsError.ThrowExceptionForHR(hr); // Create a surface from our alpha bitmap surface.Dispose(); vmr9mixerBitmap = null; //Release this alpha bitmap source. if (alphaBitmap != null) { alphaBitmap.Dispose(); } } return; } else { try { alphaBitmap = BitmapGenerator.GenerateAlphaBitmap(); // Create a surface from our alpha bitmap if(surface == null) surface = new Surface(device, alphaBitmap, Pool.SystemMemory); // Get the unmanaged pointer unmanagedSurface = surface.GetObjectByValue(DxMagicNumber); if (vmr9mixerBitmap == null) vmr9mixerBitmap = (IVMRMixerBitmap9)vmr9; // Set Alpha Bitmap Parameters for using a Direct3D surface alphaBmp = new VMR9AlphaBitmap(); alphaBmp.dwFlags = VMR9AlphaBitmapFlags.EntireDDS; alphaBmp.pDDS = unmanagedSurface; alphaBmp.rDest = GetDestRectangle(); alphaBmp.fAlpha = 1.0f; // Set Alpha Bitmap Parameters hr = vmr9mixerBitmap.SetAlphaBitmap(ref alphaBmp); DsError.ThrowExceptionForHR(hr); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } 

And here is the thread waiting for the update event.

  Thread overlayupdatethreadhandle = new Thread(new ThreadStart(overlayupdatethread)); overlayupdatethreadhandle.Start(); private void overlayupdatethread() { do { overlayupdateeventhandle.WaitOne(); ShowHideBitmap(GlobalVar.m_ShowOverlay); } while (true); } 

I tried updating this overlay using a timer that worked in the background at intervals of 100 ms. Using a timer worked well, but using a timer has a poor choice for this operation. So I switched with the concept of streaming.

Why does the interface crash when called from a stream and works well when called from menu options? Do I have to take care of some special thing? I even tried a parameterized thread, but no luck.

Thanks in advance for your help.

EDIT: If ShowHideBitmap is called from the main theme, everything works fine. If ShowHideBitmap is called from a workflow, the COM object throws an exception. How to handle this crossflow operation?

+7
source share
2 answers

The exception is ratty, not uncommon in COM. Actually it means: "I don’t know how to give you a link to an interface that you can use from a workflow." What is a common type of failure, such COM components are simply not thread safe. And they impose it, or taking care of it, and automatically redirect calls from the workflow to the owner’s thread. Or, not allowing you to use them from another thread, because marshaling will be pointless, making it too slow. VMR belongs to the latter category.

This is very unlike .NET, it also has many classes that are completely unsafe. The basic material is also, for example, none of the collection classes. But it allows you to use these classes in a thread anyway, leaving it to you to make it thread safe. This often goes wrong, of course, using the right lock is a skill.

COM has always been knowledgeable about design threads. With the philosophy that carving is very difficult to get right, that’s why smart people should take care of it. Which works fantastically 95% of the time. And gives you a lot of migraine the rest of the time. A type of migraine caused by severe diagnosis of poor perfusion when COM takes care of dressing. And a crappy bug report when he doesn't.

Well, I can’t, you really need to use this interface from the same thread that created the VMR instance. Nothing like this.

+3
source

I had an E_NOINTERFACE error when trying to use the Listener / Event handler object from the Delphi library. To overcome the issue of marshaling and different threads, I saved a thread manager that assigns a listener and then uses it to fire events.

Interfaces:

 [ComVisible(true)] [Guid("2FFC2C20-A27B-4D67-AEA3-350223D3655F")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDataSystemInterfaceEventListener { void OnIntializeCompleted(int status); void OnTerminateCompleted(int status); void OnRunCompleted(int status); } [ComVisible(true)] [Guid("B9953413-A8C9-4CE2-9263-B488CA02E7EC")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDataSystemInterface { void Intialize(string config); void StartRun(string conditions); void StopRun(); void Terminate(); IDataSystemInterfaceEventListener Listener { get; set; } } 

Then the implementation is executed (notification Dispatcher.CurrentDispatcher)

 [ComVisible(true)] [Guid("0818F830-DA37-4167-BF31-3A2C55A9BF2B")] public class DataSystemModule : IDataSystemInterface { private Dispatcher m_dispatcherListener = null; private IDataSystemInterfaceEventListener m_listener = null; public IDataSystemInterfaceEventListener Listener { get { return m_listener; } set { m_dispatcherListener = Dispatcher.CurrentDispatcher; m_listener = value; } } } 

Then in the code:

 if (Listener != null) { m_dispatcherListener.Invoke((Action)delegate() { Listener.OnTerminateCompleted((int)TerminateStatus.Completed); }); } 

Without a dispatcher, if the Listener is called on another thread, this will result in an error

+1
source

All Articles