Синхронизация входного и выходного видеопотоков с выборочной обработкой
Проблема
Во многих проектах, связанных с обработкой видеопотоков (кодирование, декодирование, конвертация), возникает проблема рассогласования частот входного и выходного потоков данных. Это приводит к визуальным артефактам, таким как:
-
“Резаный кадр” – когда изображение содержит части предыдущего и нового кадров (см. пример на рисунке ниже).
-
“Биение” – нестабильная частота вывода, заметная глазу.

Причины проблемы
Основная причина – отсутствие синхронизации между входным и выходным потоками. Например:
-
Если камера передаёт данные с частотой 50 Гц, а дисплей работает на 60 Гц, задача вывода кадров будет вынуждена либо пропускать, либо дублировать кадры, что приводит к биению.
-
Если задача ожидает и приход нового кадра, и момент вывода на дисплей, задержки приводят к “резаным кадрам”.
Решение
Для устранения дефектов необходимо разделить выполняемую работу между несколькими задачами и наладить межзадачное взаимодействие. При этом следует придерживаться принципа:
Каждая задача должна ждать только одного события.
Основные правила синхронизации
-
Одна точка синхронизации с таймаутом – задача может иметь несколько точек ожидания (например, ожидание семафора
semTake()
или ожидание сообщения из очередиmsgQReceive()
), но только одна из них должна иметь ненулевой таймаут. Остальные –NO_WAIT
. -
Обязательное ожидание – если задача по смыслу не должна ждать синхронизации с другими задачами, в её цикл добавляется
taskDelay()
с таймаутом ≥1, чтобы дать время на исполнение менее приоритетным задачам.
Схема взаимодействия задач
Для синхронизации потоков используются три задачи:

Синхронизация A-B
Для захвата кадров от камеры и вывода их на экран следует использовать две задачи, обозначенные на рисунке буквами A и B. Задача A постоянно находится в ожидании кадров от камеры, следующих с частотой F1. Как только кадр принят, она сразу же отправляет указатель на принятые данные в очередь сообщений A-B. Задача B постоянно находится в ожидании обратного хода луча от дисплея, выводящего видеопоток с частотой F2. Как только задача B получает управление, она производит смену экранных областей, забирает все имеющиеся данные из очереди сообщений A-B и выводит только последний принятый кадр в конструируемую экранную область. При этом выходной видеопоток модифицируется следующим образом:
- при F1 > F2 каждый N-ый кадр входного потока будет отброшен, где N=F1/(F1-F2);
- при F1 < F2 каждый N-ый кадр выходного потока будет являться повтором предыдущего, где N=F2/(F2-F1).
Например, при конвертации видеопотка из 60 в 50 Гц отбрасывается каждый шестой кадр, а при конвертации видеопотка из 50 в 60 Гц каждый шестой кадр будет повтором предыдущего. Такой подход устраняет оба дефекта. Биения не будет, так как процесс отбрасывания (дублирования) происходит равномерно и не заметен глазу. Эффекта “резаного кадра” не будет, потому что задача B производит смену экранных областей строго в синхронизации с обратным ходом луча дисплея.
Синхронизация A-B-C
В проектах, обеспечивающих не только захват/вывод видеопотока, но и его обработку, появляется ещё одна функция, требующая синхронизации. Время обработки одного кадра может сильно изменяться в зависимости от содержащейся в нём информации, а значит если встроить такую обработку в одну из задач захвата/вывода видеопотока, она может повлиять на стабильность работы этой задачи. Рекомендуется вынести обработку видеопотока в отдельную задачу. На рисунке она обозначена буквой C. Эта задача также имеет всего одну точку синхронизации с ожиданием – она ожидает поступления новых данных от задачи A. После окончания обработки очередного кадра она помещает итог своей работы (информацию об объектах в кадре) в очередь C-B. Если же обработка одного кадра заняла слишком много времени и в очереди A-C накопилось несколько кадров, то лишние кадры игнорируются и задача C сразу переходит к обработке последнего пришедшего кадра. Задача B периодически проверяет наличие сообщений в очереди C-B и обновляет информацию на дисплее по мере поступления новых данных. Если же новые данные ещё не готовы, то используются данные обработки предыдущего кадра. Таким образом задача обработки не влияет на входной и выходной видеопотоки и своевременно обновляет информацию на дисплее о найденных объектах.
Распределение приоритетов
Для правильной работы описываемой схемы межзадачного взаимодействия необходимо правильно распределить приоритеты выполнения задач. Прежде чем говорить о значениях приоритетов для каждой из задач следует пояснить общий принцип работы приоритетов.
Задачи в MULTEX-ARM получают доступ к ресурсам процессора в соответствии с их приоритетами. Сначала выполняется наиболее приоритетная задача, затем она встаёт на ожидание некоторого события и передаёт управление менее приоритетной. Когда все задачи с высоким приоритетом находятся в состоянии ожидания всё оставшееся время достаётся наименее приоритетной задаче, которая является фоновой по отношению к остальным. Исполнение фоновой задачи может быть прервано в любое время, если произошло одно из событий, ожидаемых высокоприоритетными задачами.
Исходя из этого распределение приоритетов в описываемой схеме должно выполняться следующим образом:
- Задача C требует наибольших вычислительных затрат, а значит должна получить максимально возможное время выполнения. Так как остальные задачи почти ничего не вычисляют и большую часть времени ждут внешних событий, то задача C должна получить самый низкий приоритет. Таким образом она может занять всё свободное время процессора, оставаясь в фоне.
- Задача A зависит от внешнего события – прихода кадра – и не должна опаздывать с началом его обработки. Все остальные задачи зависят уже от неё, а значит задача A должна получить самый высокий приоритет.
- Задача B является в данной схеме второстепенной. Подготовка кадра и вывод на экран осуществляется аппаратными средствами процессора, а значит не требует больших вычислительных мощностей. Следовательно, приоритет задачи B должен быть ниже, чем у задачи A, но выше, чем у задачи C.
Например, в ряде проектов применяются следующие значения приоритетов для таких задач: A-10, B-11, C-25.
Вывод
Предложенная схема решает проблему рассогласования частот и обеспечивает плавный вывод видеопотока без артефактов. Ключевые принципы:
✔ Разделение задач (захват, вывод, обработка).
✔ Ожидание только одного события в каждой задаче.
✔ Правильное распределение приоритетов.
Этот метод применим не только в видеосистемах, но и в других задачах, где требуется синхронизация разночастотных потоков данных.