149 / 13 / 8
Регистрация: 02.02.2014
Сообщений: 275
1

Работа с HDMI 2.1

21.01.2022, 14:32. Показов 518. Ответов 11
Метки нет (Все метки)

Привет всем!

Есть мысль сделать устройство, которое будет анализировать на лету картинку, проходящую через HDMI 2.1, и на основе неё управлять светодиодными лентами. Это довольно типовая задача, но есть нюанс - картинка 4K 120 Гц с HDR (10 бит/к). Я вижу два пути - сначала пропускаем через сплиттер, один сигнал идет на экран, второй сначала уменьшаем по герцовке/разрешению/разрядности, потом пихаем в наше устройство. Но здесь меня беспокоит, не создаст ли HDMI сплиттер дополнительной задержки в 1 или более кадров. Второй вариант - сделать устройство, которое пропускает через себя оригинальный сигнал и попутно его анализирует, и делает это построчно, т.к. не запоминая себе в буфер кадр, для того, чтобы минимизировать задержку.

Если я правильно понимаю, то первый вариант в принципе реализуем на просто хорошем контроллере, единственное - сплиттер, даунскейлер и... что-то, преобразующее HDR в SDR, здесь должны быть очень суровые, чтобы выдержать сигнал 4K 120 Гц HDR. Второй вариант, насколько я понимаю, реализуем только средствами FPGA, причем очень неслабых, т.к. поток информации очень большой.

Для такой картинки я с трудом нашел даже простой переходник DisplayPort -> HDMI, а с обработкой, как я подозрвеаю, дела обстоят еще хуже.

Пока я воспринимаю такую реализацию как слишком сложную и дорогую по отношению к результату (пониженная задержка), но может быть, сейчас уже есть какие-то инструменты, чтобы HDMI сигнал с такими параметрами обрабатывать не используя профессиональное/промышленное оборудование?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.01.2022, 14:32
Ответы с готовыми решениями:

Через что подключить DVI-HDMI или HDMI-HDMI?
Какое подключение лучше? На мониторе встроенные колонки отсутствуют.

Выбор hdmi (hdmi to hdmi) для тв
Добрый день! Подскажите пожалуйста, хочу купить hdmi провод - от компьютера к телевизор(купил...

Некорректная работа hdmi и монитора
Здравствуйте. Имеется следующая машина: intel core i3 2130 3,4GHz asus p8h61 m lx3 r2.0 radeon...

GeForce GT520 одновременная работа hdmi и dvi
Друг хочет купить какую-то простенькую видеокарту для просмотра HD видео, так что сейчас не...

11
Native x86
Эксперт Hardware
5167 / 3016 / 872
Регистрация: 13.02.2013
Сообщений: 9,635
21.01.2022, 19:22 2
Цитата Сообщение от VBDUnit Посмотреть сообщение
не создаст ли HDMI сплиттер дополнительной задержки
Нет, сплиттер ничего не буферизирует.

Цитата Сообщение от VBDUnit Посмотреть сообщение
будет анализировать на лету картинку, проходящую через HDMI 2.1, и на основе неё управлять светодиодными лентами
FPGA очень сложно и дорого, даунскейлер и контроллер тоже не факт что проще и дешевле.

Я бы взял сплиттер, дешевый x86 miniPC, USB-карту видео-захвата, USB-RGB-контроллер для лент, и написал не очень сложную программу на любом высоко-уровневом языке.
1
149 / 13 / 8
Регистрация: 02.02.2014
Сообщений: 275
21.01.2022, 19:32  [ТС] 3
Ну тут нюанс что сигнал идёт с пк. По идее тогда проще уже прямо на нём средствами DirectX картинку анализировать. Я просто думал может можно сделать это как то с меньшей задержкой.
0
Native x86
Эксперт Hardware
5167 / 3016 / 872
Регистрация: 13.02.2013
Сообщений: 9,635
21.01.2022, 19:46 4
Цитата Сообщение от VBDUnit Посмотреть сообщение
По идее тогда проще уже прямо на нём средствами DirectX картинку анализировать
А вот насчет DirectX уже не факт.
Я не знаток DirectShow, но, помнится, начиная с Vista, подглядывать за чужим видео-потоком в реальном времени и разрешении то ли невозможно, то ли как-то очень трудно.

Тогда уж просто делать снимки полноэкранного окна плеера через банальный GetDC + BitBlt.
1
149 / 13 / 8
Регистрация: 02.02.2014
Сообщений: 275
21.01.2022, 19:54  [ТС] 5
Вроде в dx11 появился какой-то хитрый механизм, позволяющий прямо из видеопамяти копировать себе текстуру рабочего стола: https://www.codeproject.com/Ar... tX-Library

Если оно не рабочее, то тогда уже точно надо делать как Вы описали выше, GetDC+BitBlt точно не вариант, слишком большой поток данных.
0
Native x86
Эксперт Hardware
5167 / 3016 / 872
Регистрация: 13.02.2013
Сообщений: 9,635
21.01.2022, 21:11 6
Цитата Сообщение от VBDUnit Посмотреть сообщение
GetDC+BitBlt точно не вариант, слишком большой поток данных
Я так понимаю, вам нужно световое сопровождение картинки? Если на экране красное и зеленое, то зажигаем огни тех же цветов?

Для этого не обязательно хватать 120 раз в секунду, хватит и 10 раз, а с этим проблем нет и у GDI.
1
149 / 13 / 8
Регистрация: 02.02.2014
Сообщений: 275
23.01.2022, 10:54  [ТС] 7
Спасибо, попробую. Надеюсь, Вы правы и скорости хватит.
0
149 / 13 / 8
Регистрация: 02.02.2014
Сообщений: 275
01.02.2022, 15:30  [ТС] 8
К сожалению, GDI не переваривает - где-то 5 раз в секунду, при этом очень напрягает процессор. Планируется использовать всё это на разрешении 11520х2160, поэтому если оно на 4K тормозит, то дальше будет только хуже. Пытаюсь реализовать захват и уменьшение картинки экрана через DirectX.

Нашёл в целом хороший рабочий пример, где сначала идет захват, затем уменьшение средствами видеокарты (C#/SharpDX), потом копирование в ОЗУ и сохранение.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 var adapterIndex = 0; // adapter index
            var outputIndex = 0; // output index
            using (var dxgiFactory = new DXGI.Factory1())
            using (var dxgiAdapter = dxgiFactory.GetAdapter1(adapterIndex))
            using (var output = dxgiAdapter.GetOutput(outputIndex))
            using (var dxgiOutput = output.QueryInterface<DXGI.Output1>())
            {
                _device = new D3D11.Device(dxgiAdapter,
#if DEBUG
                    D3D11.DeviceCreationFlags.Debug |
#endif
                    D3D11.DeviceCreationFlags.BgraSupport); // for D2D support
 
 
 
 
                _outputDuplication = dxgiOutput.DuplicateOutput(_device); //Падаем тут. Access Denied.
 
 
 
            }
            int counter = 0;
 
            Thread.Sleep(5000);
            Text = counter.ToString();
            var ratio = 0.5; // resize ratio
 
            using (var dxgiDevice = _device.QueryInterface<DXGI.Device>())
            using (var d2dFactory = new D2D.Factory1())
            using (var d2dDevice = new D2D.Device(d2dFactory, dxgiDevice))
            {
                // acquire frame
                _outputDuplication.TryAcquireNextFrame(100_000, out var _, out var frame);
                if (frame == null)
                    throw new NullReferenceException();
                using (frame)
                {
                    // get DXGI surface/bitmap from resource
                    using (var frameDc = new D2D.DeviceContext(d2dDevice, D2D.DeviceContextOptions.None))
                    using (var frameSurface = frame.QueryInterface<DXGI.Surface>())
                    using (var frameBitmap = new D2D.Bitmap1(frameDc, frameSurface))
                    {
                        // create a GPU resized texture/surface/bitmap
                        var desc = new D3D11.Texture2DDescription
                        {
                            CpuAccessFlags = D3D11.CpuAccessFlags.None, // only GPU
                            BindFlags = D3D11.BindFlags.RenderTarget, // to use D2D
                            Format = DXGI.Format.B8G8R8A8_UNorm,
                            Width = (int)(frameSurface.Description.Width * ratio),
                            Height = (int)(frameSurface.Description.Height * ratio),
                            OptionFlags = D3D11.ResourceOptionFlags.None,
                            MipLevels = 1,
                            ArraySize = 1,
                            SampleDescription = { Count = 1, Quality = 0 },
                            Usage = D3D11.ResourceUsage.Default
                        };
                        using (var texture = new D3D11.Texture2D(_device, desc))
                        using (var textureDc = new D2D.DeviceContext(d2dDevice, D2D.DeviceContextOptions.None)) // create a D2D device context
                        using (var textureSurface = texture.QueryInterface<DXGI.Surface>()) // this texture is a DXGI surface
                        using (var textureBitmap = new D2D.Bitmap1(textureDc, textureSurface)) // we can create a GPU bitmap on a DXGI surface
                        {
                            // associate the DC with the GPU texture/surface/bitmap
                            textureDc.Target = textureBitmap;
 
                            // this is were we draw on the GPU texture/surface
                            textureDc.BeginDraw();
 
                            // this will automatically resize
                            textureDc.DrawBitmap(
                                frameBitmap,
                                new Interop.RawRectangleF(0, 0, desc.Width, desc.Height),
                                1,
                                D2D.InterpolationMode.HighQualityCubic, // change this for quality vs speed
                                null,
                                null);
 
                            // commit draw
                            textureDc.EndDraw();
 
                            // now save the file, create a WIC (jpeg) encoder
                            using (var file = File.OpenWrite($"test{counter++}.jpg"))
                            using (var wic = new WIC.ImagingFactory2())
                            using (var jpegEncoder = new WIC.BitmapEncoder(wic, WIC.ContainerFormatGuids.Jpeg))
                            {
                                jpegEncoder.Initialize(file);
                                using (var jpegFrame = new WIC.BitmapFrameEncode(jpegEncoder))
                                {
                                    jpegFrame.Initialize();
 
                                    // here we use the ImageEncoder (IWICImageEncoder)
                                    // that can write any D2D bitmap directly
                                    using (var imageEncoder = new WIC.ImageEncoder(wic, d2dDevice))
                                    {
                                        imageEncoder.WriteFrame(textureBitmap, jpegFrame, new WIC.ImageParameters(
                                            new D2D.PixelFormat(desc.Format, D2D.AlphaMode.Premultiplied),
                                            textureDc.DotsPerInch.Width,
                                            textureDc.DotsPerInch.Height,
                                            0,
                                            0,
                                            desc.Width,
                                            desc.Height));
                                    }
 
                                    // commit
                                    jpegFrame.Commit();
                                    jpegEncoder.Commit();
                                }
 
                            }
                        }
                    }
                }
                _outputDuplication.ReleaseFrame();
Это работает ровно до тех пор, пока не будет запущено полноэкранное приложение.

В случае полноэкранных приложений (протестил на Battlefield 4 и GZDoom) валится на попытке вызвать DuplicateOutput. Вроде как говорит, что нет прав.
Код
SharpDX.SharpDXException: "HRESULT: [0x80070005], Module: [General], ApiCode: [E_ACCESSDENIED/General access denied error], Message: Отказано в доступе.

Изначально это исключение было создано в этом стеке вызовов: 
    SharpDX.Result.CheckError()
    SharpDX.DXGI.Output1.DuplicateOutput(SharpDX.IUnknown)
    WinFormsApp3.Form2.button1_Click(object, System.EventArgs) в Form2.cs
    System.Windows.Forms.Control.OnClick(System.EventArgs) в Control.cs
    System.Windows.Forms.Button.OnClick(System.EventArgs) в Button.cs
    System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs) в Button.cs
    System.Windows.Forms.Control.WmMouseUp(ref System.Windows.Forms.Message, System.Windows.Forms.MouseButtons, int) в Control.cs
    System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message) в Control.cs
    System.Windows.Forms.ButtonBase.WndProc(ref System.Windows.Forms.Message) в ButtonBase.cs
    System.Windows.Forms.Button.WndProc(ref System.Windows.Forms.Message) в Button.cs
    ...
    [Стек вызовов обрезан]
От администратора запускал, не работает. Я подозреваю, что дело в каком-то монопольном использовании экрана, но думаю, что я где-то просто неправильно выставил флаги. Кто-нибудь сталкивался с этим?
0
Native x86
Эксперт Hardware
5167 / 3016 / 872
Регистрация: 13.02.2013
Сообщений: 9,635
01.02.2022, 15:53 9
Цитата Сообщение от VBDUnit Посмотреть сообщение
Планируется использовать всё это на разрешении 11520х2160
Не, ну о таком нужно сразу предупреждать.

Цитата Сообщение от VBDUnit Посмотреть сообщение
Это работает ровно до тех пор, пока не будет запущено полноэкранное приложение.
На чем вы это все проверяете? Случайно, не ноутбук с гибридным видео?
1
149 / 13 / 8
Регистрация: 02.02.2014
Сообщений: 275
01.02.2022, 16:22  [ТС] 10
Цитата Сообщение от quwy Посмотреть сообщение
На чем вы это все проверяете? Случайно, не ноутбук с гибридным видео?
Не, стационарник, довольной старый, но неплохой.

Кликните здесь для просмотра всего текста

2 х Xeon E5-2650 v.1 (каждый 2 ГГц, 8 ядер/16 потоков в каждом + HT)
GTX Titan (который самый первый, по сути GTX 780 с double и 6 Гб памяти)
64 Gb RAM DDR3 (4 х 2 каналов)
Windows 8.1 Pro


Сейчас к нему подключено два 4К экрана, пробую на 1 из них. 11520х2160 буду пускать уже на RTX 3080Ti (к сожалению, она не умеет в Windows 8.1, поэтому ждет когда я поставлю Win11) - это будет объединение трёх 4К в один виртуальный экран средствами драйвера.

Есть ещё мысль, что виновата винда, но миграция на вин 11 дело не быстрое, ибо очень много переферии и софта, поэтому я перехожу на новую очень осторожно и плавно. Пока хочу отработать другие версии.
0
Native x86
Эксперт Hardware
5167 / 3016 / 872
Регистрация: 13.02.2013
Сообщений: 9,635
01.02.2022, 16:50 11
В любом случае попробуйте инициализировать захват после запуска полноэкранного приложения.
1
149 / 13 / 8
Регистрация: 02.02.2014
Сообщений: 275
01.02.2022, 16:57  [ТС] 12
Так и делаю, у меня оно после нажатия кнопки ждёт 30 сек, потом только все инициализирует и фоткает. За эти 30 сек успеваю запустить игру.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.02.2022, 16:57
Помогаю со студенческими работами здесь

Тормоза на телевизоре LG 42LD565 при подключении к компу через HDMI-HDMI
В общем суть проблемы такова: купил fHD lcd телевизор LG 42LD565, подключил к компу через...

Подключение монитора без hdmi (dvi и vga) к видеокарте c hdmi
Добрый день! Вопрос немного странный, но хотелось бы разобраться:) У меня есть монитор IPS на 24',...

Подключение Sony KDL-32R413B к ноутбуку через HDMI-HDMI
Здрасте. Имеется телевизор Sony KDL-32R413B отдали HDMI кабель на 5 метров v1.4 Подключив...

Как грамотно электрически и безопасно соединить ПК и ТВ кабелем HDMI-HDMI?
Здравствуйте! Компьютер питается из незаземлённой двухпроводной линии (розетки), видеокарта...

При длине кабеля HDMI, связующего Пк и TV, 8 метров, нужен ли усилитель по линии HDMI?
Здравствуйте! При длине кабеля HDMI, связующего Пк и TV, 8 метров, нужен ли усилитель по линии...

Acer 8930G при подключении через HDMI-HDMI к телевизору не выдаёт картинку
Собственно, на компьютере второй экран находится без проблем. На телевизоре иногда мигает картинка...

Подключение компа к телеку через HDMI-HDMI кабель
парни у меня тож беда с подключением телек новый взял LED SAMSUNG подключил зашол в настройки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru