transmite televisor señal reconoce porque imagen funciona conectar cable agarra c# directshow pci graphedit

c# - televisor - porque mi cable hdmi no transmite imagen



¿Cómo detectar si el cable HDMI está enchufado en la tarjeta PCMCIA/no hay señal? (4)

Creo que lo acabo de descubrir! Me topé con el método de get_HorizontalLocked : get_HorizontalLocked .

Este método devuelve verdadero o falso para mí cuando la videocámara está apagada y / o el cable HDMI está desenchufado, lo cual es perfecto para mis necesidades.

DirectShowLib se puede encontrar aquí: https://sourceforge.net/projects/directshownet/files/

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using DirectShowLib; namespace Test { static class Program { [STAThread] static void Main() { using (System.Threading.Mutex mutex = new System.Threading.Mutex(false, "Global//" + appGuid)) { if (!mutex.WaitOne(0, false)) { return; } DsDevice[] capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); foreach (var device in capDevices) { if (device.DevicePath == @"@device:pnp://?/pci#ven_1131&dev_7160 &subsys_12abf50a&rev_03#6&37bccbbe&0&000800e1#{65e8773d-8f56 -11d0-a3b9-00a0c9223196}/{6f814be9-9af6-43cf -9249-c0340100021c}") { IFilterGraph2 m_FilterGraph = (IFilterGraph2)new FilterGraph(); IBaseFilter capFilter = null; ICaptureGraphBuilder2 capGraph = null; capGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); int hr; hr = capGraph.SetFiltergraph(m_FilterGraph); hr = m_FilterGraph.AddSourceFilterForMoniker(device.Mon, null, device.Name, out capFilter); IAMAnalogVideoDecoder videoDec = capFilter as IAMAnalogVideoDecoder; bool signalDetected = false; hr = videoDec.get_HorizontalLocked(out signalDetected); if (signalDetected == true) { System.Diagnostics.Process.Start( @"C:/Users/PC/Documents/HIDDEN_FOLDER/WirecastLaunch.wcst"); return; } else { // Poll for ''signal'' change } break; } } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } private static string appGuid = "z0a76b5a-02cd-15c5-b9d9-d303zcdde7b9"; } }

Estoy intentando escribir una aplicación de ayuda simple que se utiliza para indicar al usuario que encienda una videocámara si no se detecta ninguna señal, lo que en este caso significa que la videocámara está apagada y / o el cable HDMI no está enchufado a la PCMCIA. Tarjeta de captura. Si la señal está presente, lanzo la aplicación de grabación correspondiente, en este caso Wirecast.

¿Cómo podría hacer esto para crear C # en VisualStudio?

Actualizar

Creo que ahora estoy mucho más cerca al intentar una sugerencia basada en uno de los comentarios que sugieren usar GraphEdit y ver qué hay disponible en el hardware. Pude encontrar dentro de las propiedades del dispositivo de captura, un indicador de ''Señal detectada'' que cambia de 0 a 1 si la videocámara está encendida / apagada o si el cable HDMI está desenchufado, que es lo que quiero.

Ahora, ¿cómo voy a acceder a esta bandera a través del código? Creo que estoy muy cerca, pero no sé cómo acceder a la estructura de cElems y pElems desde el caGUID . cElems devuelve un valor de 3, que es el mismo número de pestañas que se muestran en la ventana de propiedades de GraphEdit que se muestra a continuación en una captura de pantalla. pElems devuelve un valor diferente cada vez que ejecuto la aplicación, así que no estoy seguro de lo que está sucediendo en esa estructura. Creo que la bandera que estoy buscando se encuentra en algún lugar dentro de esas estructuras.

Código:

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using DirectShowLib; namespace Test { static class Program { [STAThread] static void Main() { using (System.Threading.Mutex mutex = new System.Threading.Mutex(false, "Global//" + appGuid)) { if (!mutex.WaitOne(0, false)) { return; } DsDevice[] capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); foreach (var dev in capDevices) { if (dev.DevicePath == @"@device:pnp://?/pci#ven_1131&dev_7160&subsys_12abf50a&rev_03#6&37bccbbe&0&000800e1#{65e8773d-8f56-11d0-a3b9-00a0c9223196}/{6f814be9-9af6-43cf-9249-c0340100021c}") { IFilterGraph2 m_FilterGraph = (IFilterGraph2)new FilterGraph(); IBaseFilter capFilter = null; ICaptureGraphBuilder2 capGraph = null; capGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); int hr; hr = capGraph.SetFiltergraph(m_FilterGraph); hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); ISpecifyPropertyPages pProp = capFilter as ISpecifyPropertyPages; FilterInfo filterInfo; hr = capFilter.QueryFilterInfo(out filterInfo); DsCAUUID caGUID; hr = pProp.GetPages(out caGUID); Console.WriteLine(caGUID.cElems); Console.WriteLine(caGUID.pElems); // caGUID.cElems returns ''3'', which is the correct number of tabs in the property pages shown in GraphEdit. // caGUID.pElems returns a different value every time break; } } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } private static string appGuid = "z0a76b5a-02cd-15c5-b9d9-d303zcdde7b9"; } }


Esto realmente puede depender del proveedor, pero al probar con un dispositivo similar, el proveedor está escribiendo en una clave de registro personalizada cuando el dispositivo se enchufa y se retira.

  • Para detectar cambios en el registro antes y después de un evento que uso RegShot, hay un tutorial útil here que describe el proceso.
  • A partir de esto, una vez que haya determinado qué clave están actualizando, puede suscribirse a través de WMI al Registro. Echa un vistazo a esta respuesta para saber cómo hacer esto.

No puedo traducir a C # porque ya no uso Windows realmente, pero si está bien con la traducción del siguiente C ++ a C #, entonces puede usarlo.

Existe una WinAPI llamada RegisterDeviceNotification que le permite saber cuándo se enchufa un dispositivo o si se cambia su estado a través de un WinProc-Callback.

Tomado de mi Github: https://github.com/Brandon-T/HDMI

Vea también: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363480(v=vs.85).aspx y https://msdn.microsoft.com/en-us/library/windows/desktop/aa363431(v=vs.85).aspx

Lista de GUIDs que he usado en mis propios proyectos:

GUID devices[] = { {0x4D36E96E, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}, //PlugNPlay Display {0xA5DCBF10, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}, //GUID_DEVINTERFACE_USB_DEVICE {0x0850302A, 0xB344, 0x4FDA, 0x9B, 0xE9, 0x90, 0x57, 0x6B, 0x8D, 0x46, 0xF0}, //GUID_BTHPORT_DEVICE_INTERFACE {0xE6F07B5F, 0xEE97, 0x4a90, 0xB0, 0x76, 0x33, 0xF5, 0x7B, 0xF4, 0xEA, 0xA7}, //GUID_DEVINTERFACE_MONITOR {0x1CA05180, 0xA699, 0x450A, 0x9A, 0x0C, 0xDE, 0x4F, 0xBE, 0x3D, 0xDD, 0x89}, //GUID_DISPLAY_DEVICE_ARRIVAL {0x5B45201D, 0xF2F2, 0x4F3B, 0x85, 0xBB, 0x30, 0xFF, 0x1F, 0x95, 0x35, 0x99}, //GUID_DEVINTERFACE_DISPLAY_ADAPTER {0x1AD9E4F0, 0xF88D, 0x4360, 0xBA, 0xB9, 0x4C, 0x2D, 0x55, 0xE5, 0x64, 0xCD}, //GUID_DEVINTERFACE_VIDEO_OUTPUT_ARRIVAL };

Luego creo una clase para monitorear un dispositivo específico:

#include <windows.h> #include <dbt.h> #include <algorithm> class Device { private: HDEVNOTIFY hNotify; public: Device() : hNotify(NULL) {} Device(HWND window, GUID dev_guid); Device(Device&& dev) : hNotify(NULL) {std::swap(hNotify, dev.hNotify);} ~Device() {UnregisterDeviceNotification(hNotify);} Device(const Device& dev) = delete; Device& operator = (const Device& dev) = delete; Device& operator = (Device&& dev) {std::swap(hNotify, dev.hNotify);return *this;} }; Device::Device(HWND window, GUID dev_guid) : hNotify(NULL) { if (window) { DEV_BROADCAST_DEVICEINTERFACE filter; memset(&filter, 0, sizeof(filter)); filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; filter.dbcc_classguid = dev_guid; hNotify = RegisterDeviceNotification(window, &filter, DEVICE_NOTIFY_WINDOW_HANDLE); //DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES } }

Finalmente, creo una ventana / ventana de mensajes para monitorear los dispositivos:

int Create() { WNDCLASSEX wx = {0}; wx.cbSize = sizeof(WNDCLASSEX); wx.lpfnWndProc = WndProc; wx.hInstance = GetModuleHandle(NULL); wx.lpszClassName = "HDMI_MONITOR"; if (RegisterClassEx(&wx)) { MSG msg = {0}; CreateWindowEx(0, "HDMI_MONITOR", "HDMI_MONITOR", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } return 0; } //The callback function: LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static std::unique_ptr<Device> dev; switch(msg) { case WM_CREATE: { dev.reset(new Device(hwnd, devices[0])); //GUID for plug-n-play devices.. } break; case WM_DEVICECHANGE: { DEV_BROADCAST_DEVICEINTERFACE* info = (DEV_BROADCAST_DEVICEINTERFACE*) lParam; switch(wParam) { case DBT_DEVICEARRIVAL: std::cout<<"Device was plugged in/n"; break; case DBT_DEVICEREMOVECOMPLETE: std::cout<<"Device was un-plugged in/n"; break; default: std::cout<<"wParam: "<<(void*)wParam<<"/n"; break; } } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }