Помогите завести камеру

Knoppix

Модераторы: Warderer, Модераторы разделов

Ответить
Аватара пользователя
Devider
Сообщения: 476
ОС: GNU/Linux

Помогите завести камеру

Сообщение Devider »

Пытаюсь завести камеру на mk802ii. После пересборки ядра появилось /dev/video0, но cheese показывала вертикальные цветные полосы. Нагуглил, что надо включить
Device Drives > Multimedia Support > Video Capture Adapters > V4L USB Devices > <*> USB Video Class

появилось вдобавок /dev/video1 , а cheese теперь падает с
libEGL warning: DRI2: failed to authenticate

(cheese:5099): Gtk-WARNING **: Attempting to add a widget with type GtkImage to a GtkToggleButton, but as a GtkBin subclass a GtkToggleButton can only contain one widget at a time; it already contains a widget of type GtkLabel

(cheese:5099): Gtk-WARNING **: Attempting to add a widget with type GtkImage to a GtkToggleButton, but as a GtkBin subclass a GtkToggleButton can only contain one widget at a time; it already contains a widget of type GtkLabel

(cheese:5099): Gtk-WARNING **: Attempting to add a widget with type GtkImage to a GtkToggleButton, but as a GtkBin subclass a GtkToggleButton can only contain one widget at a time; it already contains a widget of type GtkLabel

(cheese:5099): Gtk-WARNING **: Attempting to add a widget with type GtkImage to a GtkButton, but as a GtkBin subclass a GtkButton can only contain one widget at a time; it already contains a widget of type GtkLabel

(cheese:5099): Gtk-WARNING **: Attempting to add a widget with type GtkGrid to a GtkToggleButton, but as a GtkBin subclass a GtkToggleButton can only contain one widget at a time; it already contains a widget of type GtkLabel

(cheese:5099): Gtk-WARNING **: Attempting to add a widget with type GtkImage to a GtkButton, but as a GtkBin subclass a GtkButton can only contain one widget at a time; it already contains a widget of type GtkLabel

** (cheese:5099): CRITICAL **: cheese_camera_device_get_uuid: assertion `CHEESE_IS_CAMERA_DEVICE (device)' failed
Ошибка сегментирования

Есть идеи?
Вложения
config.txt
(70.02 КБ) 8 скачиваний
Спасибо сказали:
IMB
Сообщения: 2561
ОС: Debian

Re: Помогите завести камеру

Сообщение IMB »

Не очень понятно какая у Вас камера, но если это камера с USB-интерфейсом и поддерживающая UVC (http://www.ideasonboard.org/uvc/), то попробуйте что-то из этого:

Код: Выделить всё

$ apt-cache search uvc
guvcview - GTK+ base UVC Viewer
uvcdynctrl - Command line tool to control v4l2 devices
uvcdynctrl-data - Command line tool to control v4l2 devices - data files
uvcdynctrl-dbg - Debug Symbols for uvcdynctrl
luvcview - USB Video Class grabber
uvccapture - USB UVC Video Class snapshot software
Спасибо сказали:
Аватара пользователя
Devider
Сообщения: 476
ОС: GNU/Linux

Re: Помогите завести камеру

Сообщение Devider »

Камера называется defender c110:
T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 3 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=064e ProdID=a116 Rev=04.25
S: Manufacturer=SuYin
S: Product=USB2.0 UVC 1.3M WebCam
S: SerialNumber=CN1316-S30B-MI034-VS-R04.02.05
C: #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=168mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=0e(video) Sub=01 Prot=00 Driver=uvcvideo
I: If#= 1 Alt= 0 #EPs= 0 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo

Хотелось бы еще v4l использовать. Попробовал vlc.Вот что получилось при выборе соответственно /dev/video0 и /dev/video1
VLC media player 2.0.3 Twoflower (revision 2.0.2-93-g77aa89e)
[0x269908] main libvlc: Запуск vlc с интерфейсом по умолчанию. Используйте 'cvlc' для запуска vlc без интерфейса.
[0x560218] access_alsa demux error: cannot open device hw for ALSA audio (Нет такого файла или каталога)
[0x550810] main input error: open of `alsa://' failed
[0x5b1ba8] xcb_xv vout display error: no available XVideo adaptor

VLC media player 2.0.3 Twoflower (revision 2.0.2-93-g77aa89e)
[0xf91908] main libvlc: Запуск vlc с интерфейсом по умолчанию. Используйте 'cvlc' для запуска vlc без интерфейса.
[0x1271838] v4l2 demux error: cannot open device '/dev/video1': No space left on device
[0x12741c0] v4l2 access error: cannot open device '/dev/video1': No space left on device
[0x126d2d0] main input error: open of `v4l2:///dev/video1' failed
Спасибо сказали:
IMB
Сообщения: 2561
ОС: Debian

Re: Помогите завести камеру

Сообщение IMB »

Используйте, думаю никто возражать не станет. :)
Если у Вас нет захвата с камеры, то проверьте что все необходимые модули загружены или включены в состав Linux.
Вот Вам ещё способ захватить с камеры - http://gstreamer.freedesktop.org/data/doc/...ns-v4l2src.html
Судя по http://www.linux.org.ru/forum/development/...d=1383560463912 Вы уже решили эту проблему.
Спасибо сказали:
Аватара пользователя
Devider
Сообщения: 476
ОС: GNU/Linux

Re: Помогите завести камеру

Сообщение Devider »

IMB писал(а):
04.11.2013 19:56
Используйте, думаю никто возражать не станет. :)
Если у Вас нет захвата с камеры, то проверьте что все необходимые модули загружены или включены в состав Linux.
Вот Вам ещё способ захватить с камеры - http://gstreamer.freedesktop.org/data/doc/...ns-v4l2src.html
Судя по http://www.linux.org.ru/forum/development/...d=1383560463912 Вы уже решили эту проблему.

Нет, это на x86_64,а теперь новая итерация, перенести это все на arm. Рад, что возражений нет, но захват не работает с приведенными выше ошибками.:) На счет модулей, все, что мне показалось необходимымя вроде включил в ядро.
Спасибо сказали:
IMB
Сообщения: 2561
ОС: Debian

Re: Помогите завести камеру

Сообщение IMB »

Devider писал(а):
04.11.2013 20:01
Нет, это на x86_64,а теперь новая итерация, перенести это все на arm. Рад, что возражений нет, но захват не работает с приведенными выше ошибками.:) На счет модулей, все, что мне показалось необходимымя вроде включил в ядро.

С использованием GStreamer мы сделали полноценную камеру на базе ARM FreeScale iMX538, поэтому могу точно утверждать, что GStreamer работает на ARM как с USB-камерами, так и с CMOS-сенсорами.
Возможно Вам поможет это:

Код: Выделить всё

#!/bin/sh

GS=gst-launch

DEF_PORT=5000
DEF_CODEC=h264
DEF_RES=640x480

usage() {
        echo -e "\n$0 [OPTIONS]\n"
        echo -e "\t-m run mode [server, client]"
        echo -e "\t-c codec (h264, mpeg4, h263, jpeg, js) [$DEF_CODEC]"
        echo -e "\t\tjpeg - hardware encode, js - software encode"
        echo -e "\t-a destination or source address"
        echo -e "\t\tnot set on client if server send on client address"
        echo -e "\t-p destination or source port [$DEF_PORT]"
        echo -e "\t-r resolution [$DEF_RES]"
        echo -e "\t-h this help"
}

run_server()
{
        if [ -z $ADDRESS ]; then
                echo "Detination address can't be empty!"
                echo
        fi

        W=`echo $RESOLUTION | cut -d'x' -f1`
        H=`echo $RESOLUTION | cut -d'x' -f2`

        CMD="$GS -v v4l2src device=/dev/video0"
        CMD=$CMD" ! video/x-raw-yuv,width=$W,height=$H"
        CMD=$CMD" ! mfw_ipucsc"
        if [ "$CODEC" != js ]; then
                CMD=$CMD" ! mfw_vpuencoder width=$W height=$H"
        elif [ "$CODEC" = js ]; then
                CMD=$CMD" ! jpegenc"
        fi

        if [ "$CODEC" = h264 ]; then
                CMD=$CMD" codec-type=std_avc ! rtph264pay pt=96"
        elif [ "$CODEC" = mpeg4 ]; then
                CMD=$CMD" codec-type=std_mpeg4 ! rtpmp4vpay send-config=true"
        elif [ "$CODEC" = h263 ]; then
                CMD=$CMD" codec-type=std_h263 ! rtph263pay pt=96"
        elif [ "$CODEC" = jpeg -o "$CODEC" = js ]; then
                [ "$CODEC" = jpeg ] && CMD=$CMD" codec-type=std_mjpg"
                CMD=$CMD" ! rtpjpegpay type=26"
        else
                echo "Unknow codec $CODEC"
                exit
        fi

        CMD=$CMD" ! udpsink host=$ADDRESS port=$PORT sync=false"

        echo $CMD
        $CMD
}

run_client()
{
        CMD="$GS -v udpsrc"

        [ -z "$ADDRESS" ] || CMD=$CMD" multicast-group=$ADDRESS"
        CMD=$CMD" port=$PORT "
        CMD=$CMD" caps=\"application/x-rtp, media=(string)video,"
        CMD=$CMD" clock-rate=(int)90000,"

        if [ "$CODEC" = h264 ]; then
                CMD=$CMD" payload=(int)96, encoding-name=(string)H264\""
                CMD=$CMD" ! rtph264depay ! ffdec_h264"
        elif [ "$CODEC" = mpeg4 ]; then
                CMD=$CMD" payload=(int)96, profile-level-id=(string)6,"
                CMD=$CMD" encoding-name=(string)MP4V-ES\""
                CMD=$CMD" ! rtpmp4vdepay ! ffdec_mpeg4"
        elif [ "$CODEC" = h263 ]; then
                CMD=$CMD" payload=(int)34, encoding-name=(string)H263\""
                CMD=$CMD" ! rtph263depay ! ffdec_h263"
        elif [ "$CODEC" = jpeg -o "$CODEC" = js ]; then
                CMD=$CMD" payload=(int)96, encoding-name=(string)JPEG\""
                CMD=$CMD" ! rtpjpegdepay ! ffdec_mjpeg"
        else
                echo "Unknow codec $CODEC"
                exit
        fi

        CMD=$CMD" ! xvimagesink"
        echo $CMD
        $CMD
}

if [ $# -eq 0 ]; then
        usage
        exit
fi

while getopts "m:c:a:p:r:hd" opt; do
        case "$opt" in
                m) MODE=$OPTARG;;
                c) CODEC=$OPTARG;;
                a) ADDRESS=$OPTARG;;
                p) PORT=$OPTARG;;
                r) RESOLUTION=$OPTARG;;
                h|\?|*) usage; exit;;
        esac
done

PORT=${PORT:-$DEF_PORT}
CODEC=${CODEC:-$DEF_CODEC}
RESOLUTION=${RESOLUTION:-$DEF_RES}

if [ "$MODE" = server ]; then
        run_server $CODEC $RESOLUTION $ADDRESS $PORT
elif [ "$MODE" = client ]; then
        run_client $CODEC $ADDRESS $PORT
else
        usage
fi

Этим скриптом я запускал тестовый pipeline на плате. Конечно его надо будет чуть "подрихтовать" под Ваши реалии ;)
Если угодно, то вот пример захвата с матриц, с USB-камерами не пробовал:

Код: Выделить всё

#include <stdio.h>
#include <argp.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#define FPS        30
#define DEVICE    "/dev/video0"
#define NUMBER    100
#define BUFFER    3
#define WIDTH    1280
#define HEIGHT    720

const char *argp_program_version = "fpsmeter 0.1.1\n"
                                "Compiled " __DATE__ " " __TIME__;
static char doc[] = "Capture frames meter";

static struct argp_option options[] = {
    {"device", 'd', "DEVICE", 0, "Capture device [" DEVICE "]", 0},
    {"fps", 'f', "FPS", 0, "Set framerate [30]", 0},
    {"number", 'n', "NUMBER", 0, "Number capture frames [100]", 0},
    {"resolution", 'r', "RESOL", 0, "Captured resolution [1280x720]", 0},
    {"mode", 'm', "MODE", 0, "Captured mode [0]", 0},
    {0, 0, 0, 0, 0, 0}
};

struct arguments {
    char            *device;
    unsigned char    fps;
    unsigned char    mode;
    unsigned short    width;
    unsigned short    height;
    unsigned int    number;
};

static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
    struct arguments *a = state->input;

    switch (key) {
        case 'd':
            a->device = arg;
            break;
        case 'f':
            a->fps = (unsigned char)atoi(arg);
            break;
        case 'n':
            a->number = (unsigned int)atoi(arg);
            break;
        case 'r':
            if (sscanf(arg, "%hux%hu", &a->width, &a->height) != 2)
                argp_error(state, "Failed parse resolution %s!\n", arg);
            break;
        case 'm':
            a->mode = (unsigned char)atoi(arg);
            break;
        default:
            return ARGP_ERR_UNKNOWN;
    }

    return 0;
}

static struct argp argp = {options, parse_opt, 0, doc, 0, 0, 0};

typedef struct {
    __u32    length;
    __u32    offset;
    void    *data;
} buf_info;

int main(int argc, char *argv[])
{
    struct arguments arg;
    struct v4l2_format fmt;
    struct v4l2_streamparm parm;
    struct v4l2_crop crop;
    struct v4l2_requestbuffers req;
    struct v4l2_buffer buf;
    enum v4l2_buf_type type;
    struct timeval tv[2];
    int fd = -1;
    unsigned char i;
    buf_info frames[BUFFER];
    unsigned int cap_number = 0;

    memset(&arg, 0, sizeof(arg));
    memset(frames, 0, sizeof(buf_info) * BUFFER);
    arg.device = DEVICE;
    arg.fps = FPS;
    arg.number = NUMBER;
    arg.width = WIDTH;
    arg.height = HEIGHT;
    arg.mode = 0;
    argp_parse(&argp, argc, argv, 0, 0, &arg);

    fd = open(arg.device, O_RDWR);
    if (fd <= 0) {
        fprintf(stderr, "Failed open %s!\n", arg.device);
        return -1;
    }

    // конфигурирование
    memset(&parm, 0, sizeof(parm));
    parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    parm.parm.capture.timeperframe.numerator = arg.fps;
    parm.parm.capture.timeperframe.denominator = 1;
    parm.parm.capture.capturemode = arg.mode;
    if (ioctl(fd, VIDIOC_S_PARM, &parm)) {
        fprintf(stderr, "Failed VIDIOC_S_PARM!\n");
        goto ERROR;
    }
    memset(&crop, 0, sizeof(crop));
    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    crop.c.width = arg.width;
    crop.c.height = arg.height;
    crop.c.top = 0;
    crop.c.left = 0;
    if (ioctl(fd, VIDIOC_S_CROP, &crop)) {
        fprintf(stderr, "Failed VIDIOC_S_CROP!\n");
        goto ERROR;
    }
    memset(&fmt, 0, sizeof(fmt));
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
    fmt.fmt.pix.width = arg.width;
    fmt.fmt.pix.height = arg.height;
    if (ioctl(fd, VIDIOC_S_FMT, &fmt)) {
        fprintf(stderr, "Failed VIDIOC_S_FMT!\n");
        goto ERROR;
    }
    memset(&req, 0, sizeof(req));
    req.count = BUFFER;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;
    if (ioctl(fd, VIDIOC_REQBUFS, &req)) {
        fprintf(stderr, "Failed VIDIOC_REQBUFS!\n");
        goto ERROR;
    }

    // запуск захвата
    for (i = 0; i < BUFFER; i++) {
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.index = i;

        if (ioctl(fd, VIDIOC_QUERYBUF, &buf)) {
            fprintf(stderr, "Failed VIDIOC_QUERYBUF!\n");
            goto ERROR;
        }

        frames[i].length = buf.length;
        frames[i].offset = buf.m.offset;
        frames[i].data = mmap(NULL, buf.length,
                PROT_READ | PROT_WRITE, MAP_SHARED, fd,
                (off_t)buf.m.offset);
        if (NULL == frames[i].data) {
            fprintf(stderr, "Failed mmap!\n");
            goto ERROR;
        }
    }
    for (i = 0; i < BUFFER; i++) {
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;
        buf.m.offset = frames[i].offset;

        if (ioctl(fd, VIDIOC_QBUF, &buf)) {
            fprintf(stderr, "Failed VIDIOC_QBUF!\n");
            goto MMAP;
        }
    }
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (ioctl(fd, VIDIOC_STREAMON, &type)) {
        fprintf(stderr, "Failed VIDIOC_STREAMON!\n");
        goto MMAP;
    }

    // получение кадров
    memset(tv, 0, 2 * sizeof(struct timeval));
    gettimeofday(&tv[0], NULL);
    while (cap_number != arg.number) {
        memset(&buf, 0, sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        if (ioctl (fd, VIDIOC_DQBUF, &buf)) {
            fprintf(stderr, "Failed VIDIOC_DQBUF!\n");
            goto MMAP;
        }

        if (ioctl(fd, VIDIOC_QBUF, &buf)) {
            fprintf(stderr, "Failed VIDIOC_QBUF!\n");
            goto MMAP;
        }

        cap_number++;
    }
    gettimeofday(&tv[1], NULL);
    fprintf(stderr, "Captured %u frames in %lu usec (%.02f FPS)\n",
            arg.number,
            (tv[1].tv_sec * 1000000 + tv[1].tv_usec) -
            (tv[0].tv_sec * 1000000 + tv[0].tv_usec),
            (float)arg.number /
            (float)(((tv[1].tv_sec * 1000000 + tv[1].tv_usec) -
                    (tv[0].tv_sec * 1000000 + tv[0].tv_usec)) / 1000000));

    // остановка потока
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (ioctl(fd, VIDIOC_STREAMOFF, &type)) {
        fprintf(stderr, "Failed VIDIOC_STREAMOFF!\n");
        goto ERROR;
    }
    for (i = 0; i < BUFFER; i++)
        munmap(frames[i].data, frames[i].length);

    close(fd);

    return EXIT_SUCCESS;

MMAP:
    for (i = 0; i < BUFFER; i++)
        munmap(frames[i].data, frames[i].length);

ERROR:
    close(fd);
    return -EXIT_FAILURE;
}

К сожалению, или радости, мне не повезло и я не имел возможности использовать полностью готовый софт, поэтому могу только порекомендовать разбить проблему на меньшие этапы - сперва добиться захвата, потом добавить кодирование и на финальном этапе трансляцию или запись в файл, смотря что Вам нужно.
И не забывайте обращаться к документации производителя, как бы она не была скудна всё же это лучше чем ничего. Так же очень часто ответ можно в исходникам, но это требует уже более кропотливой работы и часто надо знать где и что искать.
Спасибо сказали:
Ответить