Edid монитора как узнать
В ожидании ответа на xrandr обнаружение усилителя в качестве монитора возможный обходной путь - занести в черный список устройства с определенными значениями EDID . К сожалению, xrandr --verbose печатает все в формате, который является громоздким для анализа и не поддерживает запросы к отдельным устройствам, и get-edid выходные данные, кажется, не легко сопоставить xrandr с идентификаторами монитора (например DVI-1 ).
Есть ли способ получить легко разбираемый EDID для одного монитора?
Я бы пошел на xrandr разбор. Это громоздко, но вы просто напишите свой сценарий раз и навсегда, и тогда он будет работать везде.Ведущий № 1: монитор-Edid
Я не особо разбираюсь в EDID и мониторах, но я нашел этот инструмент, monitor-edid который может быть полезен и здесь.
Простите, если это не так, я пытаюсь узнать больше об этом пространстве, учитывая множество вопросов, которые вы задаете по этой теме.
Ведущий № 2: ddcontrol
Был еще один инструмент, который я нашел ddccontrol , который может помочь в получении информации, которую вы ищете.
Ведущий № 3: / sys
Наконец, пробираясь, /sys я заметил, что на различных видеоинтерфейсах свисали листовые узлы.
Однако на моем ноутбуке Lenovo эти «файлы» были пустыми, возможно, они другие в вашей системе. Я нашел эту ветку форума, которая показала пример выходных данных из VGA EDID.
Ссылки
@PeterW. - есть альтернатива, спасибо, что обратили на это мое внимание. Также инструмент находится в большинстве крупных репо. Я нашел это в Fedora 24, например, а также в CentOS. Таким образом, вы можете установить инструмент в виде двоичного файла, что, вероятно, намного проще.Вывод xrandr --props содержит шестнадцатеричные строки EDID для каждого подключенного дисплея менее подробным способом. Вот простой скрипт Python, использующий это для получения EDID для конкретного подключенного монитора.
Я не нашел других дистрибутивных инструментов CLI, которые бы работали для извлечения EDID в моей системе на базе NVidia, но большинство инструментов для анализа двоичного EDID, похоже, работают нормально.
Если вы используете x86 или powerpc arch, вы можете использовать read-edid . На Debian это доступно здесь .
Использование просто (вам нужно быть пользователем root):
а затем проанализировать структуру:
Часто это объединяется в:
Смотрите также здесь о том, как передать этот пользовательский файл edid на вашу графическую карту, используя либо:
- CustomEDID или,
- drm_kms_helper.edid_firmare
Последняя версия инструмента под названием edid-decode может анализировать информацию EDID, а также может читать и записывать текстовые и двоичные файлы EDID. Хорошо работает на выходе xrandr --verbose . Например, его можно использовать для сохранения EDID в двоичном файле:
Версия edid-decode, поставляемая с Fedora 27 (package: xorg-x11-utils), слишком старая и не работает идеально. Я использовал самую последнюю версию .
В двоичном виде EDID доступен по адресу /sys/class/drm/card%d-%s/edid , где %d представляет индекс устройства DRM (возможно, индекс GPU) и %s представляет собой идентификатор соединителя, который вы видите в xrandr выходных данных.
Чтобы просмотреть все доступные, запустите ls -1 /sys/class/drm/*/edid
Если ваш драйвер GPU не поддерживает DRM, вы не сможете получить EDID таким образом.
Чтобы просмотреть в шестнадцатеричном виде, бегите hexdump по нему.
Если вы хотите удобочитаемую форму, передайте ее edid-decode , например:
(вам может понадобиться установить его, используя менеджер пакетов, sudo apt install edid-decode для Ubuntu)
Как узнать модель и серийный номер монитора
EDID - Extended Display Identification Data - стандарт формата данных VESA, расширенные данные идентификации дисплея. Эта информация передается монитором или телевизором на устройство, которое генерирует видео сигнал. EDID содержит базовую информацию о мониторе и его возможностях, включая информацию о производителе, максимальном размере, цветовых характеристиках, заводских таймингах, границах частотного диапазона и другие технические данные. Кроме этого в EDID записаны строки, содержащие модель монитора и его серийный номер. Вот они-то нас и интересуют.
После подключения и установки драйверов монитора в систему, в реестре для него формируется соответствующая запись. Нам остается только ее найти, прочитать и извлечь нужные данные. В интернетах можно найти официальный мануал VESA по стандарту EDID.
VESA Enhanced EDID Standard (ENG)
В документе почти сотня страниц, много теории и всякой технической заумности, поскольку применение EDID очень широкое. Быстро найти нужную информацию, мягко говоря, проблематично. В английском варианте статьи на Википедии эта информация разложена более понятным образом. Итак, в структуре EDID в байтах 54-125 должны быть записаны 4 блока идентификаторов. Структура каждого идентификатора описана там же. Забегая вперед отмечу, что слово "должны" некоторые производители понимают по-своему. Например, для моего маленького китайского монитора серийный номер вообще не узнать, так как в EDID записаны два блока таймингов, диапазоны работы монитора и название модели. При парсинге такие ситуации придется учитывать.
Переходим к программированию. Несколько структур, часть из которых вы уже видели в статье про выключение мониторов. Там же описан и принцип работы с мониторами, как получить их список, как получить хэндл и прочее. Настоятельно рекомендую ознакомиться, чтобы у вас не возникало вопросов, а мне не пришлось дублировать теоретические выкладки.
- struct PHYSICAL_MONITOR
- hPhysicalMonitor dd ?
- szPhysicalMonitorDescription rw 128
- ends
- struct MONITORINFOEX
- cbSize dd ?
- rcMonitor RECT
- rcWork RECT
- dwFlags dd ?
- szDevice rb 32
- ends
- struct DISPLAY_DEVICE
- cb dd ?
- DeviceName rb 32
- DeviceString rb 128
- StateFlags dd ?
- DeviceID rb 128
- DeviceKey rb 128
- ends
- ;--------------------------------------------------------
- ; Callback-функция перебора мониторов
- ;--------------------------------------------------------
- proc MonitorEnumProc hMonitor : DWORD , hdc : DWORD , lpRect : DWORD , lParam : DWORD
- locals
- ; Количество мониторов
- num dd ?
- ; Массив PHYSICAL_MONITOR
- hMonArray dd ?
- MonArray dd ?
- Manufacturer dd ?
- CurrentValue dd ?
- MaximumValue dd ?
- CurrentS dd ?
- MaximumS dd ?
- ResS dd ?
- endl
- ; Получить количество физических мониторов
- leaeax , [ num ]
- invoke GetNumberOfPhysicalMonitorsFromHMONITOR , [ hMonitor ] , eax
- ; Физических мониторов нет
- cmp [ num ] , 0
- je . loc_ret
- ; Зарезервировать память под массив PHYSICAL_MONITOR
- moveax , [ num ]
- imuleax , sizeof . PHYSICAL_MONITOR
- invoke GlobalAlloc , GMEM_MOVEABLE + GMEM_DDESHARE , eax
- mov [ hMonArray ] , eax
- invoke GlobalLock , [ hMonArray ]
- mov [ MonArray ] , eax
- ; Получить информацию о всех физических мониторах
- invoke GetPhysicalMonitorsFromHMONITOR , [ hMonitor ] , [ num ] , [ MonArray ]
- ; Выключить все мониторы поочередно
- movecx , [ num ]
- movesi , [ MonArray ]
- . loc_monitors_loop :
- pushecx
- pushesi
- ; Информация о мониторе
- mov [ minfo . cbSize ] , sizeof . MONITORINFOEX
- invoke GetMonitorInfo , [ hMonitor ] , minfo
- mov [ dds . cb ] , sizeof . DISPLAY_DEVICE
- invoke EnumDisplayDevices , minfo . szDevice , NULL , dds , 0
- invoke RtlZeroMemory , edidmodel , 256
- invoke RtlZeroMemory , edidsn , 256
- invoke RtlZeroMemory , regstr , 256
- ; Сформировать название ключа реестра
- ; SYSTEM\CurrentControlSet\Enum\DISPLAY\
- invoke lstrcpy , regstr , szReg0
- movedi , regstr
- invoke lstrlen , edi
- addedi , eax
- ; Дописать к нему подстроку из DeviceID
- movesi , dds . DeviceID
- @ @ :
- lodsb
- oral , al
- jz . loc_no_devid
- cmpal , '\'
- jne @ b
- @ @ :
- lodsb
- oral , al
- jz . loc_no_devid
- stosb
- cmpal , '\'
- jne @ b
- ; Открыть ветку реестра
- ; HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\PHL0904\
- invoke RegOpenKey , HKEY_LOCAL_MACHINE , regstr , hKey
- oreax , eax
- ; Открыть ключ не получилось, пропускаем
- jnz . loc_no_devid
- ; Перебрать все дочерние ключи, начиная с 0
- mov [ dKeysIndex ] , 0
- . loc_scan_keys_monitor :
- ; Просканировать все ключи
- invoke RegEnumKey , [ hKey ] , [ dKeysIndex ] , buff , tmp
- oreax , eax
- jnz . loc_no_more_keys
- ; Сформировать название ключа реестра
- ; SYSTEM\CurrentControlSet\Enum\DISPLAY\PHL0904\
- invoke lstrcpy , buff2 , regstr
- ; 5&217f22ba&0&UID1048848
- invoke lstrcat , buff2 , buff
- ; \Device Parameters
- invoke lstrcat , buff2 , szReg1
- ; Открыть параметр EDID в ключе реестра
- ; HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\PHL0904\
- ; 5&217f22ba&0&UID1048848\Device Parameters
- invoke RegOpenKeyEx , HKEY_LOCAL_MACHINE , buff2 , 0 , KEY_READ , hSubKey
- oreax , eax
- ; Такого параметра нет, проверить следующий ключ
- jnz . loc_next_key
- ; Прочитать EDID
- invoke RtlZeroMemory , edid , 500h
- mov [ tmp ] , 500h
- invoke RegQueryValueEx , [ hSubKey ] , szReg2 , 0 , 0 , edid , tmp
- oreax , eax
- jnz . loc_no_edid
- ; Найти в EDID строки Serial Number и Model
- xorecx , ecx
- ; Начинаем разбор с 72-го байта
- movebx , 48h
- . loc_scan_edid :
- movesi , ebx
- addesi , edid
- movbyte [ esi + 18 ] , 0
- ; Serial Number
- cmpdword [ esi ] , 0xFF000000
- jne . loc_not_edidsn
- addesi , 5
- movedi , edidsn
- . loc_move_edidsn :
- lodsb
- cmpal , 20h
- jb . loc_next_edid
- stosb
- jmp . loc_move_edidsn
- . loc_not_edidsn :
- ; Model
- cmpdword [ esi ] , 0xFC000000
- jne . loc_next_edid
- addesi , 5
- movedi , edidmodel
- . loc_move_edidmodel :
- lodsb
- cmpal , 20h
- jb . loc_next_edid
- stosb
- jmp . loc_move_edidmodel
- . loc_next_edid :
- addebx , 18
- incecx
- cmpecx , 2
- jbe . loc_scan_edid
- . loc_no_edid :
- ; Закрыть ключ
- invoke RegCloseKey , [ hSubKey ]
- . loc_next_key :
- ; Следующий индекс
- inc [ dKeysIndex ]
- jmp . loc_scan_keys_monitor
- . loc_no_more_keys :
- invoke RegCloseKey , [ hKey ]
- . loc_no_devid :
- ; edidsn -> Serial Number, если есть
- ; edidmodel -> Model
- ; или пустые строки, если записи о мониторе в реестре нет
- invoke wsprintf , buff , mask , edidmodel , edidsn
- addesp , 16
- invoke MessageBox , 0 , buff , dds . DeviceName , 0
- . loc_next_monitor :
- ; Следующая запись из массива PHYSICAL_MONITOR
- popesi
- addesi , sizeof . PHYSICAL_MONITOR
- popecx
- subecx , 1
- jnz . loc_monitors_loop
- ; Прибраться за собой
- invoke DestroyPhysicalMonitors , [ num ] , [ MonArray ]
- ; Освободить память
- invoke GlobalUnlock , [ hMonArray ]
- invoke GlobalFree , [ hMonArray ]
- . loc_ret :
- ; Продолжаем обработку
- moveax , TRUE
- ret
- endp
Как я говорил выше, в зависимости от производителя монитора, искомых строк в EDID может вообще не оказаться, или может быть только название модели, с этим я уже столкнулся на практике. Также выяснилось, что при подключении одного и того же монитора к разным компьютерам, получаемые значения его серийного номера могут отличаться. Я не могу даже предположить, с чем это связано. Ну и теоретически, раз уж EDID хранится локально в реестре, то его можно модифицировать, изменив какие-нибудь байты и подкорректировав контрольную сумму. Так что безоговорочно доверять данным EDID не надо.
Скриншот программы Phoenix EDID Designer
Для более детального изучения структуры EDID, а также для редактирования имеющихся значений, можно воспользоваться малюсенькой утилитой Phoenix EDID Designer. Ее разработка прекращена, офсайт недоступен, последнюю версию я выложил сюда.
Phoenix EDID Designer 1.3
В приложении пример программы с исходным текстом, которая выводит название модели и серийный номер для каждого подключенного монитора.
Extended Display Identification Data (EDID) является паспортом устройств отображения (мониторов, ТВ-панелей, проекторов и т.п.). Он содержит базовую информацию об устройстве и его возможностях, включая информацию о производителе, максимальном размере изображения, цветовых характеристиках, границах частотного диапазона, а также строках, содержащих название монитора и серийный номер.
При подключении компьютера к монитору, видеокарта считывает EDID, чтобы определить характеристики монитора. После того, как данные получены, видеокарта вносит необходимые коррективы, чтобы «картинка» отображалась правильно.
Видеокарта может принять и прочитать только один EDID с подключенного дисплея. Кроме того, видеокарта может транслировать только одно видео разрешение и один тип аудио формата для подключенного дисплея.
По такому же принципу работают все современные мультимедийные источники: спутниковые приставки, медиаплееры, игровые консоли, Blu-Ray плеер, DVD и т.д. Все они запрашивают EDID у подключенного устройства отображения, перед тем как транслировать «картинку».
Когда это прямое соединение PC — дисплей или медиаплеер — телевизор, то проблем, как правило, не возникает. Но когда мы используем современное коммутационное HDMI оборудование (сплиттеры, свитчи, удлинители, матрицы и т.п.), то могут возникнуть различные нюансы.
В этом случае дополнительное преимущество будут иметь устройства, имеющие ручные EDID переключатели.
Попробуем на примере сплиттера Dr.HD SP 144 SL Plus разобрать несколько ситуаций с использованием EDID переключателя.
Общие проблемы, с которыми пользователь может столкнуться при использовании HDMI сплиттера:
1. Нет видео на одном или всех устройствах отображения
2. Нет звука на одном или всех устройствах отображения
Эти симптомы обычно возникают из-за несовместимости видео разрешений или аудио форматов телевизоров/проекторов, подключенных к сплиттеру.
Конкретное устройство - Dr.HD SP 144 SL Plus - может работать в двух основных режимах: автоматическом и ручном.
Автоматический режим работы EDID
Auto Compare HDMI OUT EDID - Автоматическое сравнение EDID на всех устройствах отображения. (На устройствах с возможностью ручного выбора EDID режимов dip переключатели находятся в режиме 1111).
В данном режиме сплиттер опрашивает EDID данные от каждого подключенного устройствах отображения и создает новый EDID, с наиболее высоким общим видео разрешением и общим поддерживаемым аудио форматом. Этот новый EDID отправляется обратно источнику видео. И он уже транслирует «картинку» с разрешением, которое поддерживается всеми устройствами отображения.
Если общих EDID данных недостаточно или они отсутствуют, то для обеспечения совместимости необходимо выставить EDID вручную.
Ручной выбор EDID
В сплиттере Dr.HD SP 144 SL Plus можно выбрать более десятка режимов EDID, в зависимости от задачи. Для этого на корпусе устройства предусмотрен dip переключатель.
Случай 1. Современный 3D телевизор и HD монитор. Источник видео — 3D видеоролик. Картинку нужно вывести на оба устройства.
1080p, 2CH AUDIO (положение dip переключателей 0001)
В данном режиме сплиттер сообщит источнику видео, что он поддерживает видео разрешение 1080p, и на оба устройствах отображения будет транслироваться картинка с одинаковым разрешением 1080p.
Случай 2. Современный 3D телевизор и HD монитор. Источник видео — 3D видеоролик. Картинку нужно вывести в 3D формате, на то устройство, которое его поддерживает.
3D, 1080p, 2CH AUDIO (положение dip переключателей 0111)
В данном режиме сплиттер сообщит источнику видео, что он поддерживает видео разрешение 3D, в результате только телевизор будет отображать картинку в формате 3D. На мониторе не будет изображения, т.к. он не поддерживает 3D.
Случай 3.Современный HD телевизор и AV ресивер. Источник видео — HD видеоролик, звук DOLBY/DTS5.1 . Картинку нужно вывести в HD формате, звук DTS5.1 подать на AV ресивер.
1080p, DOLBY/DTS 5.1 (положение dip переключателей 0010)
В данном режиме сплиттер сообщит источнику видео, что он поддерживает видео разрешение 1080p и звук DOLBY/DTS 5.1, в результате телевизор будет отображать картинку в формате 1080p, а на AV ресивер будет подаваться звук DTS 5.1.
Ну и так далее. Все режимы работы смотрите чуть ниже.
Режимы работы ручного EDID переключателя
0 0 0 0 | Настройки EDID от HDMI источника OUT1 |
0 0 0 1 | 1080p, 2CH AUDIO |
0 0 1 0 | 1080p, DOLBY/DTS 5.1 |
0 0 1 1 | 1080p, HD AUDIO |
0 1 0 0 | 1080i, 2CH AUDIO |
0 1 0 1 | 1080i, DOLBY/DTS 5.1 |
0 1 1 0 | 1080i, HD AUDIO |
0 1 1 1 | 3D,1080p, 2CH AUDIO |
1 0 0 0 | 3D, 1080p,DOLBY/DTS 5.1 |
1 0 0 1 | 3D,1080p, HD AUDIO |
1 0 1 0 | 4Kx2K, 2CH AUDIO |
1 0 1 1 | 4Kx2K, DOLBY/DTS 5.1 |
1 1 0 0 | 4Kx2K, HD AUDIO |
1 1 0 1 | 1080p, 2CH AUDIO |
1 1 1 0 | 1080p, 2CH AUDIO |
1 1 1 1 | Автоматическое сравнение EDID на всех устройствах отображения |
HDMI сплиттер с EDID переключателем как устройство согласования
Но чаще на практике возникают проблемы, если источником видео является компьютер PC или Mac.
Дело в том, что в видеокартах используются «компьютерные» видео разрешения (800x600, 1024x768, 1280x960, 1280x1024, 1680x1050 и т.д.), а большинство HDMI оборудования поддерживает работу со стандартным видео разрешением 480i/576i/480p/576p/720p/1080i/1080p/2160p.
В таком случае сплиттер Dr.HD SP 144 SL Plus может выступать в качестве устройства согласования - EDID эмулятора.
Предположим, что с видеокарты компьютера «картинку» нужно передать через HDMI удлинитель по витой паре на телевизор.
В случае, когда сплиттер отсутствует, видеокарта запрашивает EDID у HDMI удлинителя.
Случай 1. Если используется модель, построенная на технологии HDBase-T (Dr.HD EX 70 BT18Gp, EX 100 BT18Gp, EX 150 BT18Gp и т.п.), здесь вопросов не возникает. Видеокарта видит телевизор напрямую, как если бы они были соединены HDMI кабелем .
Случай 2. Если используется модель со встроенным EDID переключателем (например, Dr.HD EX 50 LIR), здесь также вопросов не возникает. Выбираем подходящий режим EDID, который согласовывает видеокарту с HDMI удлинителем.
Случай 3. Если используется модель, которая не использует технологию HDBase-T или отсутствует встроенный EDID переключатель, видеокарта не находит общего подходящего режима работы с HDMI удлинителем. В результате чего «картинка» передается с большими искажениями или не передается вовсе.
В этом случае требуется установить сплиттер Dr.HD SP 144 SL Plus (или подобный) между видеокартой и HDMI удлинителем и выбрать режим 1080p, 2CH AUDIO (положение dip переключателей 0001).
В данном режиме сплиттер сообщит видеокарте, что он поддерживает видео разрешение 1080p, и на HDMI удлинитель будет транслироваться «картинка» с разрешением 1080p, которая в итоге отобразится на телевизоре.
Рекомендации по подключению
При коммутации HDMI оборудования рекомендуем соблюдать следующую последовательность включения оборудования:
Ранее в статье Учим iCEstick передавать видео-сигнал по VGA мы узнали, как работает VGA. Однако кое-что осталось за кадром. Когда я подключаю VGA-кабель к ноутбуку и говорю xrandr , программа выводит список разрешений, поддерживаемых монитором. Как она получает эту информацию?
Оказывается, что в каждом VGA-кабеле есть шина I2C. Под нее отведены пины 12 (SDA) и 15 (SCL). Ну раз такое дело, давайте возьмем HydraBus и подключимся к этим пинам:
Просканируем адреса на шине:
i2c1> scanDevice found at address 0x37
Device found at address 0x50
Device found at address 0x51
Device found at address 0x52
Device found at address 0x53
Device found at address 0x54
Device found at address 0x55
Device found at address 0x56
Device found at address 0x57
Из всех этих устройств нас интересует устройство с адресом 0 x 50. Если честно, я не знаю, для чего нужны остальные, и есть ли они на всех мониторах. Итак, с этого устройства нам нужно прочитать 128 байт:
Первые 8 байт представляют собой фиксированный заголовок. Следующие два байта 04 72 хранят три буквы имени производителя, по пять бит на каждую букву:
>>> "<:08b>".format(0x04)'00000100'
>>> "<:08b>".format(0x72)
'01110010'
>>> chr(ord('A') - 1 + 0b00001)
'A'
>>> chr(ord('A') - 1 + 0b00011)
'C'
>>> chr(ord('A') - 1 + 0b10010)
'R'
Дальше мы немного пропустим и рассмотрим байты 35-37 (нумерация байт начинается с нуля): B3 0C 00 . Это битовая маска, отражающая поддержку дисплеем «традиционных» разрешений и FPS. Декодируется она следующим образом:
1 - 720×400 @ 70 Hz
0 - 720×400 @ 88 Hz
1 - 640×480 @ 60 Hz
1 - 640×480 @ 67 Hz
0 - 640×480 @ 72 Hz
0 - 640×480 @ 75 Hz
1 - 800×600 @ 56 Hz
1 - 800×600 @ 60 Hz
0 - 800×600 @ 72 Hz
0 - 800×600 @ 75 Hz
0 - 832×624 @ 75 Hz
0 - 1024×768 @ 87 Hz, interlaced
1 - 1024×768 @ 60 Hz
1 - 1024×768 @ 72 Hz
0 - 1024×768 @ 75 Hz
0 - 1280×1024 @ 75 Hz
Ну и последний байт 00 говорит нам о том, что дисплей не поддерживает 1152 x 870 @ 75 Hz и не имеет никаких «manufacturer-specific display modes».
Далее мы видим последовательность:
Каждые два байта кодируют поддерживаемое разрешение, всего до 8 возможных дополнительных разрешений. Специальная последовательность 01 01 означает пустое значение. Попробуем декодировать первые два байта:
В первом байте закодировано количество пикселей по горизонтали. Во втором байте старшие два бита 01 означают aspect ratio 4:3 (00 = 16:10, 01 = 4:3, 10 = 5:4, 11 = 16:9), а в младших шести битах закодирована частота:
Итого получаем 1152 x 864 @ 75 Hz. По аналогии оставшиеся байты декодируются в 1280 x 1024 @ 60 Hz, 1440 x 900 @ 60 Hz, 1280 x 800 @ 60 Hz и 1920 x 1080 @ 60 Hz.
Сравним получившийся список разрешений и FPS с выводом xrandr :
VGA-1 connected (normal left inverted right x axis y axis)1920x1080 60.00 +
1280x1024 60.02
1440x900 59.89
1280x800 59.81
1152x864 75.00
1024x768 70.07 60.00
800x600 60.32 56.25
640x480 66.67 59.94
720x400 70.08
Вроде, сходится. Таким образом, еще одна загадка вселенной успешно разгадана!
Читайте также: