summaryrefslogtreecommitdiffstats
path: root/zbar/video.h
blob: fdb7394e3a3394b040d48b457924710f22a7edc7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*------------------------------------------------------------------------
 *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
 *
 *  This file is part of the ZBar Bar Code Reader.
 *
 *  The ZBar Bar Code Reader is free software; you can redistribute it
 *  and/or modify it under the terms of the GNU Lesser Public License as
 *  published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  The ZBar Bar Code Reader is distributed in the hope that it will be
 *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser Public License
 *  along with the ZBar Bar Code Reader; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 *  Boston, MA  02110-1301  USA
 *
 *  http://sourceforge.net/projects/zbar
 *------------------------------------------------------------------------*/
#ifndef _VIDEO_H_
#define _VIDEO_H_

#include "config.h"

#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include <zbar.h>

#include "error.h"
#include "image.h"
#include "mutex.h"

/* number of images to preallocate */
#define ZBAR_VIDEO_IMAGES_MAX 4

typedef enum video_interface_e
{
    VIDEO_INVALID = 0, /* uninitialized */
    VIDEO_V4L1,	       /* v4l protocol version 1 */
    VIDEO_V4L2,	       /* v4l protocol version 2 */
    VIDEO_VFW,	       /* video for windows */
    VIDEO_DSHOW	       /* direct show */
} video_interface_t;

typedef enum video_iomode_e
{
    VIDEO_READWRITE = 1, /* standard system calls */
    VIDEO_MMAP,		 /* mmap interface */
    VIDEO_USERPTR,	 /* userspace buffers */
} video_iomode_t;

typedef struct video_state_s video_state_t;

struct zbar_video_s {
    errinfo_t err;	    /* error reporting */
    int fd;		    /* open camera device */
    unsigned width, height; /* video frame size */

    video_interface_t intf;   /* input interface type */
    video_iomode_t iomode;    /* video data transfer mode */
    unsigned initialized : 1; /* format selected and images mapped */
    unsigned active	 : 1; /* current streaming state */

    uint32_t format;	   /* selected fourcc */
    unsigned palette;	   /* v4l1 format index corresponding to format */
    uint32_t *formats;	   /* 0 terminated list of supported formats */
    uint32_t *emu_formats; /* 0 terminated list of emulated formats */

    struct video_resolution_s *res; /* 0 terminated list of resolutions */

    struct video_controls_s *controls; /* linked list of controls */

    unsigned long datalen; /* size of image data for selected format */
    unsigned long buflen;  /* total size of image data buffer */
    void *buf;		   /* image data buffer */

    unsigned frame; /* frame count */

    zbar_mutex_t qlock;		/* lock image queue */
    int num_images;		/* number of allocated images */
    zbar_image_t **images;	/* indexed list of images */
    zbar_image_t *nq_image;	/* last image enqueued */
    zbar_image_t *dq_image;	/* first image to dequeue (when ordered) */
    zbar_image_t *shadow_image; /* special case internal double buffering */

    video_state_t *state; /* platform/interface specific state */

#ifdef HAVE_LIBJPEG
    struct jpeg_decompress_struct *jpeg; /* JPEG decompressor */
    zbar_image_t *jpeg_img;		 /* temporary image */
#endif

    /* interface dependent methods */
    int (*init)(zbar_video_t *, uint32_t);
    int (*cleanup)(zbar_video_t *);
    int (*start)(zbar_video_t *);
    int (*stop)(zbar_video_t *);
    int (*nq)(zbar_video_t *, zbar_image_t *);
    /** set value of video control
     *  implemented by v4l2_set_control()
     *  @param name name of a control, acceptable names are listed
     *         in processor.h
     *  @param value pointer to value of a type specified by flags
     */
    int (*set_control)(zbar_video_t *, const char *name, void *value);
    /** get value of video control
     *  implemented by v4l2_get_control()
     *  @param name name of a control, acceptable names are listed
     *         in processor.h
     *  @param value pointer to a receiver of a value of a type
     *         specified by flags
     */
    int (*get_control)(zbar_video_t *, const char *name, void *value);

    void (*free)(zbar_video_t *);

    zbar_image_t *(*dq)(zbar_video_t *);
};

/* video.next_image and video.recycle_image have to be thread safe
 * wrt/other apis
 */
static inline int video_lock(zbar_video_t *vdo)
{
    int rc = 0;
    if ((rc = _zbar_mutex_lock(&vdo->qlock))) {
	err_capture(vdo, SEV_FATAL, ZBAR_ERR_LOCKING, __func__,
		    "unable to acquire lock");
	vdo->err.errnum = rc;
	return (-1);
    }
    return (0);
}

static inline int video_unlock(zbar_video_t *vdo)
{
    int rc = 0;
    if ((rc = _zbar_mutex_unlock(&vdo->qlock))) {
	err_capture(vdo, SEV_FATAL, ZBAR_ERR_LOCKING, __func__,
		    "unable to release lock");
	vdo->err.errnum = rc;
	return (-1);
    }
    return (0);
}

static inline int video_nq_image(zbar_video_t *vdo, zbar_image_t *img)
{
    /* maintains queued buffers in order */
    img->next = NULL;
    if (vdo->nq_image)
	vdo->nq_image->next = img;
    vdo->nq_image = img;
    if (!vdo->dq_image)
	vdo->dq_image = img;
    return (video_unlock(vdo));
}

static inline zbar_image_t *video_dq_image(zbar_video_t *vdo)
{
    zbar_image_t *img = vdo->dq_image;
    if (img) {
	vdo->dq_image = img->next;
	img->next     = NULL;
    }
    if (video_unlock(vdo))
	/* FIXME reclaim image */
	return (NULL);
    return (img);
}

/* PAL interface */
extern int _zbar_video_open(zbar_video_t *, const char *);

#endif