Типа зависит от требований. Если вы знаете, что у вас всегда будет 6 каналов со скоростью 60 кадров в секунду и что процесс захвата/кодирования/сохранения займет менее 1/60 секунды, то кодировать один поток на канал будет проще всего. Но имейте в виду, что если кодирование или сохранение иногда занимает слишком много времени, вы не получите следующий кадр по расписанию.
Вы можете использовать конвейерный подход (аналогичный вашему второму варианту), но не для каждого потока. То есть, если бы вы могли иметь один поток, который ничего не делает, кроме чтения и сохранения кадра из каждого канала 60 раз в секунду. Эти кадры попадают в очередь Captured. У вас есть отдельный поток (или, возможно, несколько потоков), читающий из очереди Captured, кодирующий данные и сохраняющий результаты в очереди вывода. Наконец, один или несколько потоков вывода читают очередь вывода и сохраняют закодированные данные.
Очереди являются общими, так что все потоки кодирования, например, читают из одной и той же захваченной очереди и записывают в одну и ту же очередь вывода. Большинство современных языков программирования имеют эффективные потокобезопасные очереди. У многих есть такие структуры, которые не требуют напряженного ожидания. То есть потоки Encoding могут ожидать незанятости в очереди Captured, если она пуста. Потоки будут уведомлены, когда что-то помещается в очередь. См., например, BlockingCollection
в .NET или ConcurrentLinkedQueue
в Java.
Эта модель хорошо масштабируется. Если, например, вам нужно больше потоков кодирования, чтобы не отставать от пропускной способности, вы можете просто увеличить их количество. Вы можете получить, например, два потока захвата, 8 кодировщиков и один поток вывода. Вы можете сбалансировать его в зависимости от вашей рабочей нагрузки.
Что касается планирования, я подозреваю, что вы хотели бы, чтобы ваши потоки захвата работали на периодической основе (т.е. раз в 1/60 секунды или независимо от вашей частоты кадров). Потоки кодирования и вывода должны быть настроены на ожидание в соответствующих очередях. Например, у потока вывода нет причин постоянно опрашивать очередь вывода на наличие данных. Вместо этого он может простаивать (ожидать) и получать уведомления, когда пакет помещается в очередь вывода.
Детали того, как это сделать для видеокодера, могут сделать подход излишне запутанным. Я действительно не знаю. Если кодировщику требуется информация о состоянии конкретного канала, это становится более сложным. Это особенно сложно, если учесть, что модель позволяет двум кодировщикам работать с кадрами из одного и того же канала. Если это произойдет, вам нужно каким-то образом упорядочить вывод.
Ваш первый подход самый простой, и именно его я бы сделал для первого варианта своей программы. Если это не может поддерживать необходимую вам пропускную способность, я бы рассмотрел более сложные подходы.
04.05.2015