Difference between revisions of "Nc3x3"

From ElphelWiki
Jump to: navigation, search
Line 1: Line 1:
 +
Here is a link to babelfish translation into English (not very good quality, of course) - [http://babelfish.altavista.com/babelfish/trurl_pagecontent?lp=ru_en&url=http%3A%2F%2Fwiki.elphel.com%2Findex.php%2FNc3x3]
 
Архитектура nc3x3
 
Архитектура nc3x3
  

Revision as of 07:16, 15 September 2005

Here is a link to babelfish translation into English (not very good quality, of course) - [1] Архитектура nc3x3

nc3x3 разрабатывается с целью унификации работы с камерами на уровне user-space на стороне камеры; реализации "многозадачной" работы - т.е. одновременное вещание потоков с разными настройками, получение одиночных кадров без остановки потоков, работа системы автоэкспозиции в режиме "простоя" камеры etc. Реализация в виде ряда изменений (хаков) в монолитное ядро; вся основная работа осуществляется в двух модулях - nc3x3_io и nc3x3

nc3x3_io реализует ряд служебных (скрытых) интерфейсов в /dev/nc3x3/.xxx, предоставляет интерфейс и настройку в момент запуска io операций с FPGA, SDRAM(к которой нет прямого интерфейса через CPU) и сенсором. После загрузки модуля через .fpga.jtag осуществляется запись прошивки FPGA, и запись через другие интерфейсы ряда других таблиц/настроек.

nc3x3 предоставляет три интерйфеса для приложений - /dev/nc3x3/frame, /dev/nc3x3/stream, /dev/nc3x3/ctrl; предоставляет API для подгружаемых модулей, выполняющих функции автоэкспозиции, автофокусировки etc.

frame позволяет получить одиночный кадр в RAW или JPEG(или ключевой кадр Theora) с настройками "по умолчанию", которые изменяются через интерфейс ctrl, либо конкретно заданными. Сценарий работы с интерфейсом:
1. open() - Открытие файла. Если операция неудачна, значит система по той или иной причине отказывает в обслуживании - через некоторое время можно повторить попытку (т.е. если система перегружена запросами в очереди)
2.1. ioctl() - Опционально. Получение характеристик камеры - т.е. пределы разрешений, параметров экспозиции, формат сжатия - так же доступно через интерфейс ctrl.
2.2. ioctl() - Постановка задачи. Задаются параметры экспозиции, качество сжатия etc.
2.3. ioctl() - Проверка нормализованных параметров (т.е. все параметры запроса буду выровнены на границы значений и допустимый шаг изменения значений).
3. ioctl() - Подтверждение запроса. Приложение подтверждает запрос и переходит в состояние ожидания результата.
4. poll(), ioctl(), read() - приложение ожидает результат. После получения подтверждения о готовности задания, забирает результат.
5.1. read() - чтение данных "классическим" методом;
5.2. работа в "ускоренном" режиме - через mmap или прямой отправке через сокет (UDP или TCP)
5.2. ioctl() - получение описания задания - время начала экспозиции, размер кадра, указатель на области памяти;
5.2.1. mmap() - доступ через область памяти к данным
5.2.2. mmap() - запись заголовков RTP или других непосредственно в память, ioctl() - настройка параметров сокета, send(soket, addr) - отправка через сокет с прямым доступом к памяти (как сейчас реализовано в 323 камере), опционально - ioctl() - сброс сокета в нормальный режим.
6. close() - закрытие файла интерфейса

stream предоставляет практически те же услуги, за исключением того, что после получения первого запрошенного кадра, сразу же будет обрабатываться следующий кадр из потока. При этом через ioctl() можно менять различные настройки потока - экспозицию etc...

ctrl позволяет менять настройки кадра по умолчанию - т.е. какими будут настройки, если приложение сразу после открытия интерфейса выдаст запрос на получение кадра без изменения его параметров - это частично позволит работать по аналогии с нынешним режимом работы камеры; также предоставляет изменять настройки политики многозадачного режима настройки - например, возможно ли одновременное открытие двух интерфейсов stream, как часто в режиме вещания потока можно получать одиночные кадры через frame, использовать ли автоэкспозицию, и если да, то какой из зарегестрированных модулей etc.


Многозадачный режим

После открытия интерфейса для каждого приложения создается (в модуле ядра) запись task, в которой хранятся параметры кадра. После установки и подтверждения параметров кадра - в момент собственно запроса кадра, планировщих ставит задание в очередь.

При одновременном работе двух потоков видео, с учетом равномерной нагрузки, будет наблюдаться следующая картина, в силу логики работы сенсора (на примере разрешения 2048x1536):
одновременно работают два потока, т.е. жва приложения открыли интерфейсы stream. Первый - 2048x1536, воторой - тоже, с биннингом в 4 - т.е. примерно 640x480; на первом потоке сенсор выдает 12fps максимально, на втором - 48fps, т.е. времена кадров - 1/12s == 4/48s, 1/48s.
первый поток забрал кадр, в момент экспозиции сенсор был перепрограммирован на параметры второго потока с применением к следующему кадру;
прошел кадр 640x480, который нельзя использовать;
пошел "рабочий кадр" 640x480, во время которого сенсор перепрограммирован на 2048x1536;
бракованый кадр 2048x1536;
нормальный кадр 2048x1536. получается, что для потока 2048x1536 fps упадет до 4.8s в такой ситуации. (как и для второго). Пропорции нагрузок кадров, как и разрешения, можно менять, добиваясь приемлемых для конкретного случая результатов.

В случае, если в 333 реализовать binning в FPGA, т.е. один и тот же кадр будет дважды сжиматься в FPGA ("один к одному, и с каким-либо коэффециентом сжатия"), то от сенсора не будет бракованных кадров, и падение fps для кадров в высоком разрешении будет меньше, или равно, чем в два раза.

В случае с автоэкспозицией ситуация намного приятнее - при изменении параметров до 25% кадр не будет бракованным - в верхней (нижней) своей части он будет с прежней экспозицией, в нижней - с новой, после чего следующие кадры будут однородно засвеченные. При этом латентность системы автоэкспозиции будет не меньше чем в 4 кадра.


Применение web-интерфейса управления

Запушенный стример может управляться в общем случаем двумя методами - через клиентское приложение, или через web-интерфейс. В первом случае все ясно - управление идет через сеть (RTSP), и стример сам меняет параметры через открытый им stream интерфейс.
Во втором случае уже не все так прозрачно - т.к. каждый открытый интерфейс stream имеет свой непересекающийся контекст, то как тогда изменять параметры не из стримера?
1. Через управляющий интерфейс ctrl производить выбор контекста, и "копаться чужими руками" в его внутренностях.
2. Использовать средства межпроцессного взаимодействия.
3. Открывать в стримере сокет для такого случая, в CGI - через него подключаться, и стример сам будет менять необходимые параметры.

В третьем случае, т.к. связь будет осуществляться через loopback интерфейс, потери производительности будут перед вторым вариантом незначительные, но реализация намного упростится - через это же соединение можно будет так же и поределять, запущен ли стример.


На данный момент пока все.