1 /*
2 * Copyright (C) 2011 Texas Instruments
3 * Author: Rob Clark <rob.clark@linaro.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
18 #ifndef UTIL_H_
19 #define UTIL_H_
21 #include <stdio.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <assert.h>
29 #include <omap_drm.h>
30 #include <omap_drmif.h>
32 /* align x to next highest multiple of 2^n */
33 #define ALIGN2(x,n) (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
35 #ifndef __cplusplus
36 typedef enum {
37 false = 0,
38 true = 1
39 } bool;
40 #endif
42 #include "list.h"
44 /* Display Interface:
45 *
46 * Could be either KMS or X11 depending on build and
47 * environment. Some of details of opening/connecting, allocating buffers,
48 * etc, differ. The intention is just to provide as simple as possible
49 * abstraction to avoid lots of duplication in each test app to handle
50 * both cases.
51 */
53 struct buffer {
54 uint32_t fourcc, width, height;
55 int nbo;
56 struct omap_bo *bo[4];
57 uint32_t pitches[4];
58 struct list unlocked;
59 bool multiplanar; /* True when Y and U/V are in separate buffers. */
60 int fd[4]; /* dmabuf */
61 bool noScale;
62 };
64 /* State variables, used to maintain the playback rate. */
65 struct rate_control {
66 int fps; /* When > zero, we maintain playback rate. */
67 long last_frame_mark; /* The time when the last frame was displayed,
68 * as returned by the mark() function. */
69 int usecs_to_sleep; /* Number of useconds we have slep last frame. */
70 };
72 struct display {
73 int fd;
74 uint32_t width, height;
75 struct omap_device *dev;
76 struct list unlocked;
77 struct rate_control rtctl;
79 struct buffer ** (*get_buffers)(struct display *disp, uint32_t n);
80 struct buffer ** (*get_vid_buffers)(struct display *disp,
81 uint32_t n, uint32_t fourcc, uint32_t w, uint32_t h);
82 int (*post_buffer)(struct display *disp, struct buffer *buf);
83 int (*post_vid_buffer)(struct display *disp, struct buffer *buf,
84 uint32_t x, uint32_t y, uint32_t w, uint32_t h);
85 void (*close)(struct display *disp);
86 void (*disp_free_buf) (struct display *disp, uint32_t n);
88 bool multiplanar; /* True when Y and U/V are in separate buffers. */
89 struct buffer **buf;
90 };
92 /* Print display related help */
93 void disp_usage(void);
95 /* Open display.. X11 or KMS depending on cmdline args, environment,
96 * and build args
97 */
98 struct display * disp_open(int argc, char **argv);
100 /* free allocated buffer */
101 void disp_free_buffers(struct display *disp, uint32_t n);
102 /* Close display */
103 static inline void
104 disp_close(struct display *disp)
105 {
106 disp->close(disp);
107 }
109 /* Get normal RGB/UI buffers (ie. not scaled, not YUV) */
110 static inline struct buffer **
111 disp_get_buffers(struct display *disp, uint32_t n)
112 {
113 return disp->get_buffers(disp, n);
114 }
116 /* Get video/overlay buffers (ie. can be YUV, scaled, etc) */
117 struct buffer ** disp_get_vid_buffers(struct display *disp, uint32_t n,
118 uint32_t fourcc, uint32_t w, uint32_t h);
120 /* flip to / post the specified buffer */
121 int
122 disp_post_buffer(struct display *disp, struct buffer *buf);
124 /* flip to / post the specified video buffer */
125 int
126 disp_post_vid_buffer(struct display *disp, struct buffer *buf,
127 uint32_t x, uint32_t y, uint32_t w, uint32_t h);
129 /* Get plane (id = 1) for every connector and update the overlay */
130 int
131 get_overlay_plane(struct display *disp, struct buffer *buf);
133 /* allocate a buffer from pool created by disp_get_vid_buffers() */
134 struct buffer * disp_get_vid_buffer(struct display *disp);
135 /* free to video buffer pool */
136 void disp_put_vid_buffer(struct display *disp, struct buffer *buf);
138 /* helper to setup the display for apps that just need video with
139 * no flipchain on the GUI layer
140 */
141 struct buffer * disp_get_fb(struct display *disp);
144 /* V4L2 utilities:
145 */
147 struct v4l2;
149 /* Print v4l2 related help */
150 void v4l2_usage(void);
152 /* Open v4l2 (and media0??) XXX */
153 struct v4l2 * v4l2_open(int argc, char **argv, uint32_t *fourcc,
154 uint32_t *width, uint32_t *height);
156 /* Share the buffers w/ v4l2 via dmabuf */
157 int v4l2_reqbufs(struct v4l2 *v4l2, struct buffer **bufs, uint32_t n);
159 int v4l2_streamon(struct v4l2 *v4l2);
160 int v4l2_streamoff(struct v4l2 *v4l2);
162 /* Queue a buffer to the camera */
163 int v4l2_qbuf(struct v4l2 *v4l2, struct buffer *buf);
165 /* Dequeue buffer from camera */
166 struct buffer * v4l2_dqbuf(struct v4l2 *v4l2);
168 /* Other utilities..
169 */
170 extern int debug;
172 int check_args(int argc, char **argv);
174 void fill(struct buffer *buf, int i);
176 #define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 ))
177 #define FOURCC_STR(str) FOURCC(str[0], str[1], str[2], str[3])
179 /* Dynamic debug. */
180 #define DBG(fmt, ...) \
181 do { if (debug) fprintf(stderr, fmt "\n", ##__VA_ARGS__); } while (0)
183 #define MSG(fmt, ...) \
184 do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); } while (0)
185 #define ERROR(fmt, ...) \
186 do { fprintf(stderr, "ERROR:%s:%d: " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); } while (0)
188 #ifndef container_of
189 #define container_of(ptr, type, member) \
190 (type *)((char *)(ptr) - (char *) &((type *)0)->member)
191 #endif
193 #ifndef MIN
194 # define MIN(a,b) (((a) < (b)) ? (a) : (b))
195 #endif
197 #ifndef MAX
198 # define MAX(a,b) (((a) > (b)) ? (a) : (b))
199 #endif
201 #ifndef PAGE_SHIFT
202 # define PAGE_SHIFT 12
203 #endif
205 #ifndef PAGE_SIZE
206 # define PAGE_SIZE (1 << PAGE_SHIFT)
207 #endif
209 /* align x to next highest multiple of 2^n */
210 #define ALIGN2(x,n) (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
212 #include <sys/time.h>
213 static inline long
214 mark(long *last)
215 {
216 struct timeval t;
217 gettimeofday(&t, NULL);
218 if (last) {
219 long delta = t.tv_usec - *last;
221 /* Handle the case, where the seconds have changed.
222 * TODO: keep the whole timeval struct, to be able to cope with
223 * more than one second deltas? */
224 if (t.tv_usec < *last)
225 delta += 1000000;
227 *last = t.tv_usec;
228 return delta;
229 }
230 return t.tv_usec;
231 }
233 #endif /* UTIL_H_ */