Merhaba Yığın Taşma üyeleri,QueryInterface, E_NOINTERFACE ile çalışmıyor C#
Ben C# programlama için yeni biriyim. Temel bir kamera akışı geliştiriyorum ve yine de uygulamayı yakaladım. Kullanıcı hala harekete geçtikten sonra, VMR9'un bitmap karıştırma konseptini kullanarak bunu üst üste görüntüleyeceğim.
Yaptıklarımı?
- ben here
- Birinci gerekli tüm filtreler arabirimleri C# direkt gösteri kütüphanesinin kullanımını olsun yapıyorum. Ekli yakalama cihazını bulun. Kaynak filtre ile Render akışı ve PREVIEW pin için vmr9 olarak adlandırıldı. Kaynak filtresi, örnek kapmak ve STILL PIN için null renderer.
- Üç menü düğmesi kullanıyorum -> hala al, bindirmeyi göster ve bindirmeyi gizle.
- Bu kitaplıkta sağlanan bitmap karıştırıcı örneğini kullanıyorum.
- Kullanıcı Take Still menüsüne her bastığında, görüntü masaüstüne kaydedilir ve yeniden küçük boyutlu olarak yeniden boyutlandırılır ve video bindirmesinde görüntülenir.
- Yerleşimi göster ve bindirme çağrılarını gizleme VMH9BitmapMixer arabiriminin vmr9 filtresinden sorgulanmasını gerçekleştiren ShowHideBitmap() öğesini VMR9AlphaBitmap yapısını doldurur ve ardından IVMRMixerBitmap9.SetAlphaBitmap işlevini çağırır.
Hangi sorunla karşılaşıyorum? Ben menü seçeneği ile ShowHideBitmap() ararsanız
- hala aldıktan sonra, alınan hareketsiz görüntü bindirmesi üzerinde mükemmel güncellenmektedir.
- Bu, hareketsiz görüntü kaydedildiğinde otomatik yer paylaşımını otomatik olarak gerçekleştiren başka bir seçenektir. Etkinlik tabanlı iş parçacığı oluşturup EventWaitHandle kullanılarak oluşturulan güncelleme olayını beklemeyi başardım. Samplegrabber BufferCB işlevinden dönmeden önce bu güncelleştirme olayını ayarlıyorum. Sırayla bekleyen iplik ile devam eder. İç iş parçacığı ShowHideBitmap işlevini çağırırım. Bu senaryoda, aşağıdaki gibi hata iletisi alıyorum. İşte
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)
//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);
}
}
}
Ve burada iplik güncelleme olayı için bekler olduğunu.
Thread overlayupdatethreadhandle = new Thread(new ThreadStart(overlayupdatethread));
overlayupdatethreadhandle.Start();
private void overlayupdatethread()
{
do
{
overlayupdateeventhandle.WaitOne();
ShowHideBitmap(GlobalVar.m_ShowOverlay);
} while (true);
}
Arka planda çalışan, 100 ms aralıklarla çalışan zamanlayıcıyı kullanarak bu yerleşimi güncelleştirmeyi denedim. Zamanlayıcıyı kullanmak iyi çalışıyordu, ancak bu işlem için zamanlayıcıyı kullanmak kötü bir seçimdir. Bu yüzden iş parçacığı konsepti ile taşındım.
Bu özellik, iş parçacığından arama yaparken başarısız oluyor ve menü seçeneklerinden arama yaparken iyi çalışıyor mu? Özel bir şeyle ilgilenmem gerekiyor mu? Parametrized ipliği denedim, ama şans yok. Yardımlarınız için şimdiden
teşekkürler.
DÜZENLEME: Ana iş parçacığından ShowHideBitmap çağrılırsa, her şey düzgün çalışır. Çalışan iş parçacığından ShowHideBitmap çağrılırsa, COM nesnesi özel durum oluşturur.Bu çapraz iş parçacığı işlemek nasıl?
+1. güzel soru. Tamamen emin olmadığım için yorum yap ... Beklenilen sıralama: Çoğu COM nesnesinin tek bir iş parçacığından çağrılması beklenir ... Birden çok iş parçacığı olarak çağırabilirseniz, belgelerinizin büyük olasılıkla açıkça çağırması gerekir. (Ayrıca, nesne çapraz iş parçacığına erişmeden önce diğer iş parçacığı üzerinde COM başlatmanız gerekebileceğini de hatırlıyorum). –
Merhaba Alexei, evet haklısın. Ana iş parçacığı dışındaki birden çok iş parçacığından COM nesnesinin çağrılması bu hatayı oluşturuyor. Hatta bu vmr9mixerBitmap arabirimini başlatmayı denedim Ana iş parçacığı ve aynı ShowHideBitmap işlevini kullanarak (Bu işlevde oluşturmak yerine), ancak sonuç aynıdır. COM başlatmak, ana iş parçacığı arabirimi almalı ve iş parçacığı boyunca aynı arabirimi kullanmalıyım? İş parçacığı üzerinden erişilen bu COM nesnesinin ayrıntılı açıklaması var mı? – Spark
Temel VMR arabirimleri, COM kurallarını ihlal eden öğeler arasında iletilebilir. Yerel kodda olsa da, yönetilmeyen. C# COM interopunda bu kirli hilelerin farkında değil ve bunun bir sorun olabileceğini varsayalım: arayüzü marşlamayla geçmeye çalıştığında, bunu yapamaz, arayüzleri kaybeder ve bunları kullanamazsınız. iş parçacığı üzerinde. –