Eye of the xakep Fagot (salieff@mail.ru) Хакер, номер #095, стр. 095-124-4 while(true) { if (ioctl(vdev_fd, VIDIOCSYNC, &vmmap.frame)!=0) return false; memcpy(work_frame_buf, vbuf_ptr+videobuf.offsets[vmmap.frame], vmmap.width*vmmap.height*videopict.depth/8); vmmap.frame++; if (vmmap.frame>=(size_t)videobuf.frames) vmmap.frame=0; if (ioctl(vdev_fd, VIDIOCMCAPTURE, &vmmap)!=0) return false; ProccessFrame(work_frame_buf); } Ну и, конечно же, хочется подстраивать такие параметры изображения, как яркость, контраст и т.д. Делается это с помощью того же ioctl'а и той же структуры, которыми мы выставляли глубину цвета и палитру: КОД videopict.brightness=my_br; videopict.hue=my_hue; videopict.colour=my_col; videopict.contrast=my_cnt; videopict.whiteness=my_wht; if (ioctl(vdev_fd, VIDIOCSPICT, &videopict)!=0) return false; Руководствуясь всем упомянутым, я написал класс-обертку QCE_SPCA_Camera для работы со своей камерой (pulbic-интерфейс этого класса можно найти в соответствующей врезке). Собственный видеоплеер Чтобы иметь широкие возможности постобработки, вроде цветокоррекции и масштабирования, и при этом не грузить процессор, я решил выводить картинку посредством OpenGL. Так как в качестве интерфейсной библиотеки мы выбрали QT, то и OpenGL я привернул через QGLWidget, который перерисовывался по таймеру. Полезная функциональная нагрузка тут невысока, виджет берет у камеры буфер кадра (немного подкорректированный по размерам под нужды OpenGL) и накладывает его, как текстуру, на прямоугольник, заранее имеющий цвет, призванный произвести цветокоррекцию. Текстурные координаты вычисляются с расчетом софт-зума: КОД glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_BGR, GL_UNSIGNED_BYTE, qce_cam->getGLFrame()); glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); glColor3f(qce_cam->r_koeff, qce_cam->g_koeff, qce_cam->b_koeff); glBegin(GL_POLYGON); glTexCoord2f(0+zoom_koeff*x2y_koeff, 0+zoom_koeff); glVertex2i(-1, 1); glTexCoord2f(qce_cam->gl_coord_x-zoom_koeff*x2y_koeff, 0+zoom_koeff); glVertex2i(1, 1); glTexCoord2f(qce_cam->gl_coord_x-zoom_koeff*x2y_koeff, qce_cam->gl_coord_y-zoom_koeff); glVertex2i(1, -1); glTexCoord2f(0+zoom_koeff*x2y_koeff, qce_cam->gl_coord_y-zoom_koeff); glVertex2i(-1, -1); glEnd(); Далее, используя буфер аккумуляции, мы корректируем яркость перед окончательной отрисовкой кадра: КОД glAccum(GL_ACCUM, 1.0); glAccum(GL_RETURN, qce_cam->bright_koeff); Если карточка хоть как-то способна ускорять графику, то решение использовать OpenGL должно дать неслабый выигрыш в производительности по сравнению с софтверной математической обработкой каждого кадра. Также я привернул слева от виджета с кадрами ползунки, позволяющие менять яркость, контраст, разрешение и т.д., и связал их с соответствующими методами интерфейсного класса камеры. LPT, лирика Мы будем управлять моторами через DATA-биты LPT-порта. На моей схеме они обозначены синим цветом. Контроллер позволяет нам добиться прямого соответствия: когда мы подаем единички на какой-либо data-бит, на соответствующую обмотку подается 12 вольт. Так как я решил писать в порты ввода-вывода из user-space, моя программа будет работать только под root'ом. Это не есть хорошо, но зато избавляет нас от необходимости написания драйвера kernel-space и расширения этого номера журнала до 500 страниц ;). Data-байт для LPT1 лежит по адресу 0x378. Мы должны получить разрешение туда писать и начать это делать: |