Как воспроизводить WebRTC видео на Qt клиенте

Что ж... Недавно я увлекся C++, поэтому давайте разберемся в какой-нибудь технологии и напишем по ней статью. Мой выбор пал на WebRTC и клиент на Qt.

Типизированный язык программирования

Что ж... Недавно я увлекся C++, поэтому давайте разберемся в какой-нибудь технологии и напишем по ней статью. Мой выбор пал на WebRTC и клиент на Qt.

Мы живем в эпоху, когда ИИ стал доступен каждому. Но за магией PyTorch скрывается колоссальная инженерная работа и сложные вычислительные процессы, которые для большинства остаются черным ящиком.
Это четвертая статья из цикла От MNIST к Transformer, цель которого пошагово пройти путь от простого CUDA ядра до создания архитектуры Transformer - фундамента современных LLM моделей. Мы не будем использовать готовые высокоуровневые библиотеки. Мы будем разбирать, как все устроено под капотом, и пересобирать их ключевые механизмы своими руками на самом низком уровне. Только так можно по настоящему понять как работают LLM и что за этим стоит. В этой статье мы разберем как работает градиентный спуск, реализуем его и обучим нашу модель для распознования mnist датасета.
Приготовьтесь, будет много кода на C++ и CUDA, работы с памятью и погружения в архитектуру GPU. И конечно же математика что за этим стоит. Поехали!

Одной из самых сложных частей C++ до сих пор считаются правила поиска имён, и ошибки связанные с name lookup проявляются обычно уже в рантайме. Код компилится и даже работает какое-то время, но при свете луны ведёт себя не так как ожидает программист. За простыми идентификаторами скрывается многоуровневая система областей видимости, категорий имён и специальных правил, и очень многое в нашем текущем стандарте растёт прямиком из восьмидесятых, частенько без изменений. Давайте посмотрим как компилятор видит имена в C++, какие области видимости существуют и почему они ведут себя по-разному.
В C++ есть несколько типов областей видимости, вы наверное сходу назовёте глобальное пространство имён, область параметров шаблона, область видимости класса и область параметров функции, но также есть блочная область видимости и область видимости перечислений. Между этими областями есть исторически сложившаяся асимметрия, которая частенько удивляет: два объявления using, которые вводят одно и то же имя в одну и ту же область видимости внутри пространства имён компилятор съест без возражений, но если попытаться сделать то же самое других областях видимости, то получим ошибку на повторное объявление. В серии статей про "нескучное программирование" я разбираю скользкие случаи и как мы докатились до такого. Это продолжение темы, начатой в "Важны ли компилятору имена", поэтому чтобы картинка была цельной, лучше пробежать её по диагонали.

Благими намерениями вымощена дорога в ад. Или как погоня за оптимизацией и производительностью может нарушить фундаментальные математические принципы.

В C++ уже есть корутины. Есть диапазоны. Есть готовые библиотеки.
Но это не мешает взять гаечный ключ и начать собирать генератор вручную.
В предыдущей статье макросы внезапно начинают изображать из себя язык: DO, LET, IS управляют препроцессорным ритуалом и создают DSL. Это синтаксис. Это оболочка. Это фронтенд.
(чтение предыдущей статьи необязательно для понимания этой)
Но ведь есть не только синтаксис, можно создать и конкретную семантику — генераторы.
В этой статье я строю велосипедный генератор. Самый честный.

В статье проектируется с нуля мобильное устройство для измерение емкости на микроконтроллере ATmega8.

Александр Лонин, руководитель группы полигонального моделирования, C3D Labs, рассказывает о функциональности и перспективах развития модуля C3D PolyShaper. Рассматриваются методы создания и обработки полигональных объектов, новые алгоритмы сшивки и улучшения в триангуляции, а также диагностика и исправление дефектов сеток. Автор делится планами по реверс-инжинирингу органических форм, работе с неявными поверхностями и учету неманифолдности в булевых операциях.
Мы консолидировали все наработки по полигональному моделированию, результатом чего стал новый модуль в составе C3D Toolkit — C3D PolyShaper. Этот модуль официально зарегистрирован в реестре отечественного программного обеспечения. Он представляет собой набор классов и функций для работы с полигональными объектами и топологией. Рассмотрим текущую функциональность модуля, направления разработки и перспективы дальнейшего развития.
Полигональный объект с топологией может быть получен несколькими способами: путем конвертации из ранее существовавшего объекта MbMesh, считыванием данных из файлов форматов JT, STL и OBJ, созданием на основе параметрической оболочки или построением вручную. При чтении данных из файла необходимо восстановить топологическую информацию — другими словами, выполнить сшивку модели. Алгоритм сшивки был усовершенствован и теперь способен обрабатывать случаи с совпадающими треугольниками, что особенно актуально при работе с моделями строительных конструкций.

Всем привет, дорогие читатели! Расскажу вам о том как сделать интернет-радио на «скорую руку» без особых хлопот.

Ключевые аспекты проектирования и реализации SCADA-систем в автоматизированных системах управления технологическими процессами (АСУТП). Основное внимание уделяется интеграции с базами данных, такими как SQL Server, и использованию протокола OPC UA для взаимодействия с контроллерами.
Рассматривается процесс подключения к контроллерам с использованием библиотеки open62541, включая настройку безопасности и создание подписок для мониторинга данных.

В прошлую пятницу я объяснял джуну, почему его код на отсортированном массиве работает в шесть раз быстрее, чем на неотсортированном. Тот же массив, тот же алгоритм, и те же данные. Просто в другом порядке. Джун смотрел на меня как на сумасшедшего и, честно говоря, я его понимаю.
Потому что ответ звучит безумно: процессор внутри вашего ноутбука постоянно пытается предсказать будущее. Буквально. Он гадает, какая ветка if выполнится ещё до того, как условие будет вычислено. И на отсортированных данных ему угадывать проще.
Ну, давайте разбираться.

Логирование есть практически в каждом C++ проекте. Почти любой сервис, демон или библиотека рано или поздно обрастает строками вроде LOG_INFO(...) или logger.debug(...).
Чаще всего библиотека выбирается по привычке или популярности — spdlog, quill, easylogging++ и т.п. При этом редко кто проверяет, какую цену приложение платит за логирование.
В высоконагруженных системах логирование может выполняться:

В конце 2020 года я купил MacBook Pro 13 на процессоре Apple M1, очень хотелось испытать процессоры на архитектуре ARM. Почти сразу на чипе Apple M1 был найден вычислительный блок для матричных операций Apple AMX. Для Apple AMX не было документации, он не использовался в Apple Accelerate, но несколько энтузиастов занимались реверс-инжинирингом и анализом производительности ("https://github.com/corsix/amx").
В 2024 году вышли компьютеры на базе семейства процессоров Apple M4, у которых блок AMX задействован для выполнения инструкций из Scalable Matrix Extension 2 (сайт ARM недоступен в РФ) (ARM SME2).
В статье рассмотрим использование расширения ARM SME2 на примере умножения заполненных матриц. Увидим, как выжать максимум из процессора и получить прирост производительности в десятки раз.

Привет, Хабр! Я — Владимир Балун, и это — вторая часть материала о пакете с отпугивающим названием «unsafe» в Go и том, чем он может быть реально полезен. В первой части мы рассмотрели его содержимое, особенности и нюансы, оптимизации кода с использованием unsafe — все это вы можете освежить в памяти по ссылке.
Сегодня перейдем непосредственно к той самой «магии»: трюки, хаки, советы и лучшие практики с моей стороны.

Итак, я решил довести до реально работающего проекта превосходный эмулятор синтезатора Roland JV880. Это рэковый модуль (без клавиатурный), сделанный на базе синтезатора JV80. Соответственно он поддерживает все карты расширения этого синтезатора и почти все MIDI команды.

Это не отдельная статья, а продолжение статьи про теорию объектов в с++, почему объекты в плюсах такие какие есть. Все завершенные главы я также выкладываю на github'e в английском и русском варианте. Продолжаем разбираться в теории С++...
Отдельного разговора заслуживает идентичность объектов, потому что в реальном мире конкретные сущности обладают идентичностью и Сократ останется Сократом независимо от того, перекрасил ли он волосы, сменил адрес или умер, а государство остаётся тем же государством, даже если меняет флаг, конституцию или размер населения.
Чтобы отразить это в программе, объекты, представляющие конкретные сущности, нуждаются в своём определении идентичности, которая отделена от текущего состояния. Удобный способ ввести такую идентичность будет сделать некий токен идентичности, уникальное значение, которое выражает "кто это", а не "в каком он сейчас состоянии". Таким токеном может быть, например, адрес объекта в памяти, индекс в массиве, или табельный номер сотрудника в кадровой системе и проверяя равенство токенов идентичности, мы фактически проверяем тождественность объектов: один и тот же объект или разные.
На протяжении жизни программы конкретный объект может менять свои токены идентичности, потому что его могут переместить в другой участок памяти или переложить из одного контейнера в другой, или назначить ему новый идентификатор, но логическая идентичность сохраняется, если мы поддерживаем сопоставление между "старым" и "новым" токеном.

Множество Мандельброта. 80-бит FPU x87. OpenMP - параллельным программированием на уровне многопоточности. Синий, зеленый и красный - синусоидальными и косинусоидальными волнами: 127 + 127 cos(2 PI a / 255) и 127 + 127 sin(2 PI a / 255). DwmFlush - синхронизация с монитором 60 fps. Суперсэмплинг 2x2 (4 прохода). Делал я. Посмотрите - движется! Я сделал на g++. Свободно распространяемого компилятора языка C++. Скачайте и посмотрите! Это экзешник, в ГитХаб.
github: Download Latest Version Windows And Source code
Самое полезное - это увеличиваем / уменьшаем и центрируем. Вы на экран любое из множество Мандельброта. Какое вам нравится? Какое интересное? Вы можете все! И потом запишется в файл Mandelbrot.txt - три строки из файла. Вещественная часть центра и мнимая часть центра и ширина видимой области. Потом другая программа читает Mandelbrot.txt и создает Mandelbrot.bmp и уже не суперсэмплинг 2x2 (4 прохода) а 8x8 (64 прохода)!

Всё началось с эксперимента. На основной работе руководство довольно настойчиво рекомендовало использовать ИИ в разработке. В какой-то момент мне стало интересно, насколько далеко можно зайти в этом направлении. Можно ли написать реальное десктопное приложение так, чтобы основную часть кода писал ИИ?
Не в смысле «иногда подсказать синтаксис» или «помочь найти ошибку». А именно в буквальном смысле — чтобы код писал ИИ, а человек формулировал задачи и проверял результат.
Для эксперимента нужна была задача, которая, с одной стороны, достаточно реальная, а с другой — не связана напрямую с рабочими проектами.
В итоге кандидатов оказалось два.
Первый вариант — написать утилиту для расчёта коэффициентов цифровых фильтров. Такие инструменты используются для расчёта фильтров с заданными характеристиками — например, с нужной формой АЧХ, ограниченной задержкой и длиной фильтра.
Задача инженерная и интересная.
Но была причина отказаться от этой идеи. Похожий инструмент уже существовал внутри рабочих проектов, и смешивать рабочий код с личными экспериментами мне не хотелось.
Поэтому в итоге победил второй вариант — написать десктопное приложение для записи звука с бинауральной головы.
Про саму голову я уже писал на Хабре:
https://habr.com/ru/articles/1007864/
Если коротко, идея бинауральной записи довольно простая. Берётся макет головы с ушами, в ушных каналах устанавливаются микрофоны, и звук записывается примерно так, как его слышал бы человек.

Привет, Хабр!
В одной из прошлых своих статей, пару лет назад, я уже описывал реализацию дешевого самодельного датчика качества воздуха на базе сенсора BME680. Но прошло время, многое изменилось, и теперь возникла потребность в подобном устройстве на новом месте. Недавно на одном маркетплейсе мне попалась комбинированная плата с датчиками ENS160+AHT21, которая подходит под мои задачи, а что в итоге получилось, читайте далее.

UHT сгенерировал 4294 строки кода из одного моего заголовочного файла. Имена свойств, смещения в памяти, флаги сериализации, exec thunks для каждой функции - всё, чтобы движок в runtime знал о классе то, что C++ забывает после компиляции. Это третья и последняя статья в серии про внутренности Unreal Engine: K2Node → Blueprint VM → рефлексия. Разбираем, что внутри этих четырёх тысяч строк, зачем каждая из них, и как ими пользуются Details panel, GC, репликация и сама Blueprint VM.

Вот так. Впервые в мире. Суперсэмплинг (SSAA) — ресурсоемкий метод сглаживания, увеличивающий число выборок на пиксель для повышения качества изображения. При значении 8x (N=8) сцена рендерится в разрешении, в 8 раз превышающем целевое, по обеим осям, создавая 64 (или 8 х 8) выборки на пиксель. Изображение просчитывается в более высоком разрешении, а затем принудительно уменьшается до разрешения дисплея, устраняя лесенки и улучшая чёткость. Это очень высокая нагрузка! Это не 1920 на 1080 пикселя а в 8x8 больше - 15360 на 8640 пикселя! Такое никто, кроме меня, делает в мире. Для множество Мандельброта.
Это маленькая утилита из командной строке. Которая либо читает Mandelbrot.txt три строки из файла - клавиша 7. И создает Mandelbrot.bmp
Либо клавиша 1-6 - это одно из шести разных мест множество Мандельброта и создает Mandelbrot.bmp
Скачайте и посмотрите. Это экзешник, в ГитХаб
Скачать последнюю версию (Windows и Linux)