Я работаю над прототипом приложения, в основном написанного на Python (2.7) для исследовательского проекта. Приложение получает видеопоток mpegts с беспроводного устройства через UDP, а затем использует openCV для обработки/анализа видеокадров. Декомпрессия mpeg выполняется в моей собственной библиотеке C, которая в основном представляет собой только связанную с Python оболочку вокруг libavcodec. Приложение представляет собой приложение Python GLUT, которое использует GLUT для рисования и базовую обработку событий.Предотвращение потери пакетов UDP в фоновом потоке при большой нагрузке процессора потока в Python
Моя проблема заключается в том, что когда мой код обработки или кода кода OpenCV взимает плату с CPU, я получаю упавшие UDP-пакеты, что приводит к повреждению видеокадров. Я знаю, что UDP является «ненадежным» протоколом, и ожидается, что отброшенные пакеты ожидаются, но, к сожалению, это то, с чем мне нужно работать.
К счастью, у меня довольно приличная машина, на которой я запускаю это (MacBookPro11,3 2.8GHz quad core i7). Моя цель - создать систему, использующую потоки и очереди, в которых потребление UDP-пакетов и декомпрессии видео будет приоритетным, так что каждый распакованный фрейм будет получен без изменений (запрет фактических сетевых ошибок). Если мой рисунок или обработка основного потока не в состоянии идти в ногу с частотой кадров видеопотока, я бы хотел удалить все распакованные фреймы, чтобы поток mpeg оставался связным. Альтернативой является отказ отдельных пакетов UDP, но это приводит к поврежденному потоку изображения, который не восстанавливается в течение некоторого периода времени, т.е. я полагаю, получение следующего I-кадра. Это та ситуация, которую я пытаюсь избежать.
Я уже создал такую систему, в которой генерируется фоновый поток, который выполняет всю работу по созданию контекста декомпрессии видео и сокета UDP. Фоновая цепочка потоков бесконечно запрашивает декомпрессор для декодированных кадров, который, в свою очередь, вызывает обратный вызов по мере необходимости, который ожидает от большего количества данных из сокета (либо с помощью select, poll или blocking recv, я пробовал все три). После получения каждого нового декомпрессированного кадра фоновый поток добавляет кадры в очередь, которые потребляются в основном потоке так быстро, как могут обрабатываться. Если очередь заполнена, потому что потребитель основного потока не может идти в ногу, тогда вновь распакованный кадр просто отбрасывается и процесс продолжается.
Проблема, с которой я столкнулась, заключается в том, что даже при использовании этой системы большая нагрузка на основной поток по-прежнему вызывает удаление пакетов UDP. Это почти как если планировщик пакетов ядра, который принимает и буферизирует входящие пакеты udp, работает в моем основном потоке, который выполняет весь чертеж и обработку видеокадров (я только наполовину знаю, о чем я говорю здесь, ре. пакетный планировщик). Если я прокомментирую весь тяжелый код обработки и рисования, запущенный в основном потоке, я никогда не получаю никаких отброшенных ошибок пакетов/mpeg-декодирования.
Я уже пробовал максимизировать мой приемный буфер приема, который несколько помогает, но также увеличивает задержку, что также нежелательно, и это в конечном счете просто задерживает проблему.
Итак, мой вопрос: что я могу сделать, чтобы все мои UDP-пакеты были израсходованы и переданы в декомпрессор как можно быстрее, независимо от основной загрузки процессора?
Я попытался установить приоритет потока фонового потока на 1.0, но это не помогает. libavcodec по умолчанию порождает 9 потоков для обработки декомпрессии, но я могу опционально ограничить его 1, который я пробовал, чтобы гарантировать, что все декомпрессии происходит в одном потоке с высоким приоритетом. Глядя на мой монитор процессора, у меня есть тонны накладных расходов на моем четырехъядерном процессоре (8 с гиперпотоком, который я тоже пытался включить и выключить).
Я был бы рад сделать настройки ядра под root, если это необходимо, поскольку это всего лишь исследовательский проект, а не приложение для доставки.
Любые советы?
ТИА
Итак, сколько потоков существует и как организованы очереди? –
Есть два сценария, которые я пробовал: a) основной поток + один поток с высоким приоритетом для сокета и декомпрессия; b) основной поток + один поток с высоким приоритетом для сокета и декомпрессии + разрешающий декомпрессировать, чтобы порождать 9 дополнительных потоков (с некоторыми неизвестный приоритет). – hyperspasm