From: Pavel Machek <pavel@ucw.cz>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>,
Mauro Carvalho Chehab <mchehab@s-opensource.com>,
pali.rohar@gmail.com, sre@kernel.org,
Sakari Ailus <sakari.ailus@iki.fi>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
linux-media@vger.kernel.org, hans.verkuil@cisco.com
Subject: [patch, libv4l]: add sdlcam example for testing digital still camera functionality
Date: Sun, 21 May 2017 12:33:15 +0200 [thread overview]
Message-ID: <20170521103315.GA10716@amd> (raw)
In-Reply-To: <db37ee9a-9675-d1db-5d2e-b0549ba004fd@xs4all.nl>
[-- Attachment #1: Type: text/plain, Size: 36649 bytes --]
Add simple SDL-based application for capturing photos. Manual
focus/gain/exposure can be set, flash can be controlled and
autofocus/autogain can be selected if camera supports that.
It is already useful for testing autofocus/autogain improvements to
the libraries on Nokia N900.
Signed-off-by: Pavel Machek <pavel@ucw.cz>
diff --git a/configure.ac b/configure.ac
index f30d66d..2c8ad7e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,6 +88,247 @@ LIBDVBV5_DOMAIN="libdvbv5"
AC_DEFINE([LIBDVBV5_DOMAIN], "libdvbv5", [libdvbv5 domain])
AC_SUBST(LIBDVBV5_DOMAIN)
+# Configure paths for SDL
+# Sam Lantinga 9/21/99
+# stolen from Manish Singh
+# stolen back from Frank Belew
+# stolen from Manish Singh
+# Shamelessly stolen from Owen Taylor
+#
+# Changelog:
+# * also look for SDL2.framework under Mac OS X
+
+# serial 1
+
+dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
+dnl
+AC_DEFUN([AM_PATH_SDL2],
+[dnl
+dnl Get the cflags and libraries from the sdl2-config script
+dnl
+AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
+ sdl_prefix="$withval", sdl_prefix="")
+AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
+ sdl_exec_prefix="$withval", sdl_exec_prefix="")
+AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
+ , enable_sdltest=yes)
+AC_ARG_ENABLE(sdlframework, [ --disable-sdlframework Do not search for SDL2.framework],
+ , search_sdl_framework=yes)
+
+AC_ARG_VAR(SDL2_FRAMEWORK, [Path to SDL2.framework])
+
+ min_sdl_version=ifelse([$1], ,2.0.0,$1)
+
+ if test "x$sdl_prefix$sdl_exec_prefix" = x ; then
+ PKG_CHECK_MODULES([SDL], [sdl2 >= $min_sdl_version],
+ [sdl_pc=yes],
+ [sdl_pc=no])
+ else
+ sdl_pc=no
+ if test x$sdl_exec_prefix != x ; then
+ sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix"
+ if test x${SDL2_CONFIG+set} != xset ; then
+ SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config
+ fi
+ fi
+ if test x$sdl_prefix != x ; then
+ sdl_config_args="$sdl_config_args --prefix=$sdl_prefix"
+ if test x${SDL2_CONFIG+set} != xset ; then
+ SDL2_CONFIG=$sdl_prefix/bin/sdl2-config
+ fi
+ fi
+ fi
+
+ if test "x$sdl_pc" = xyes ; then
+ no_sdl=""
+ SDL2_CONFIG="pkg-config sdl2"
+ else
+ as_save_PATH="$PATH"
+ if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then
+ PATH="$prefix/bin:$prefix/usr/bin:$PATH"
+ fi
+ AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH])
+ PATH="$as_save_PATH"
+ no_sdl=""
+
+ if test "$SDL2_CONFIG" = "no" -a "x$search_sdl_framework" = "xyes"; then
+ AC_MSG_CHECKING(for SDL2.framework)
+ if test "x$SDL2_FRAMEWORK" != x; then
+ sdl_framework=$SDL2_FRAMEWORK
+ else
+ for d in / ~/ /System/; do
+ if test -d "$dLibrary/Frameworks/SDL2.framework"; then
+ sdl_framework="$dLibrary/Frameworks/SDL2.framework"
+ fi
+ done
+ fi
+
+ if test -d $sdl_framework; then
+ AC_MSG_RESULT($sdl_framework)
+ sdl_framework_dir=`dirname $sdl_framework`
+ SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include"
+ SDL_LIBS="-F$sdl_framework_dir -Wl,-framework,SDL2"
+ else
+ no_sdl=yes
+ fi
+ fi
+
+ if test "$SDL2_CONFIG" != "no"; then
+ if test "x$sdl_pc" = "xno"; then
+ AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
+ SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags`
+ SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs`
+ fi
+
+ sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+ sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+ sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+ if test "x$enable_sdltest" = "xyes" ; then
+ ac_save_CFLAGS="$CFLAGS"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $SDL_CFLAGS"
+ CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
+ LIBS="$LIBS $SDL_LIBS"
+dnl
+dnl Now check if the installed SDL is sufficiently new. (Also sanity
+dnl checks the results of sdl2-config to some extent
+dnl
+ rm -f conf.sdltest
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "SDL.h"
+
+char*
+my_strdup (char *str)
+{
+ char *new_str;
+
+ if (str)
+ {
+ new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
+ strcpy (new_str, str);
+ }
+ else
+ new_str = NULL;
+
+ return new_str;
+}
+
+int main (int argc, char *argv[])
+{
+ int major, minor, micro;
+ char *tmp_version;
+
+ /* This hangs on some systems (?)
+ system ("touch conf.sdltest");
+ */
+ { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
+
+ /* HP/UX 9 (%@#!) writes to sscanf strings */
+ tmp_version = my_strdup("$min_sdl_version");
+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
+ printf("%s, bad version string\n", "$min_sdl_version");
+ exit(1);
+ }
+
+ if (($sdl_major_version > major) ||
+ (($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
+ (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
+ {
+ return 0;
+ }
+ else
+ {
+ printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
+ printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro);
+ printf("*** best to upgrade to the required version.\n");
+ printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n");
+ printf("*** to point to the correct copy of sdl2-config, and remove the file\n");
+ printf("*** config.cache before re-running configure\n");
+ return 1;
+ }
+}
+
+],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+ CFLAGS="$ac_save_CFLAGS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ LIBS="$ac_save_LIBS"
+
+ fi
+ if test "x$sdl_pc" = "xno"; then
+ if test "x$no_sdl" = "xyes"; then
+ AC_MSG_RESULT(no)
+ else
+ AC_MSG_RESULT(yes)
+ fi
+ fi
+ fi
+ fi
+ if test "x$no_sdl" = x ; then
+ ifelse([$2], , :, [$2])
+ else
+ if test "$SDL2_CONFIG" = "no" ; then
+ echo "*** The sdl2-config script installed by SDL could not be found"
+ echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
+ echo "*** your path, or set the SDL2_CONFIG environment variable to the"
+ echo "*** full path to sdl2-config."
+ else
+ if test -f conf.sdltest ; then
+ :
+ else
+ echo "*** Could not run SDL test program, checking why..."
+ CFLAGS="$CFLAGS $SDL_CFLAGS"
+ CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
+ LIBS="$LIBS $SDL_LIBS"
+ AC_TRY_LINK([
+#include <stdio.h>
+#include "SDL.h"
+
+int main(int argc, char *argv[])
+{ return 0; }
+#undef main
+#define main K_and_R_C_main
+], [ return 0; ],
+ [ echo "*** The test program compiled, but did not run. This usually means"
+ echo "*** that the run-time linker is not finding SDL or finding the wrong"
+ echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
+ [ echo "*** The test program failed to compile or link. See the file config.log for the"
+ echo "*** exact error that occured. This usually means SDL was incorrectly installed"
+ echo "*** or that you have moved SDL since it was installed. In the latter case, you"
+ echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" ])
+ CFLAGS="$ac_save_CFLAGS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ LIBS="$ac_save_LIBS"
+ fi
+ fi
+ SDL_CFLAGS=""
+ SDL_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(SDL_CFLAGS)
+ AC_SUBST(SDL_LIBS)
+ rm -f conf.sdltest
+])
+
+dnl Check for SDL
+SDL_VERSION=2.0
+AM_PATH_SDL2($SDL_VERSION, sdl_pkgconfig=yes, sdl_pkgconfig=no)
+
+AM_CONDITIONAL([HAVE_SDL], [test x$sdl_pkgconfig = xyes])
+
# Define localedir
AC_DEFUN([V4L_EXPAND_PREFIX], [
$1=$2
@@ -432,5 +673,6 @@ compile time options summary
libudev : $have_libudev
QT version : $QT_VERSION
ALSA support : $alsa_pkgconfig
+ SDL support : $sdl_pkgconfig
EOF
diff --git a/contrib/test/Makefile.am b/contrib/test/Makefile.am
index 4641e21..dd06cc1 100644
--- a/contrib/test/Makefile.am
+++ b/contrib/test/Makefile.am
@@ -16,6 +16,10 @@ if HAVE_GLU
noinst_PROGRAMS += v4l2gl
endif
+if HAVE_SDL
+noinst_PROGRAMS += sdlcam
+endif
+
driver_test_SOURCES = driver-test.c
driver_test_LDADD = ../../utils/libv4l2util/libv4l2util.la
@@ -31,6 +35,10 @@ v4l2gl_SOURCES = v4l2gl.c
v4l2gl_LDFLAGS = $(X11_LIBS) $(GL_LIBS) $(GLU_LIBS) $(ARGP_LIBS)
v4l2gl_LDADD = ../../lib/libv4l2/libv4l2.la ../../lib/libv4lconvert/libv4lconvert.la
+sdlcam_LDFLAGS = $(JPEG_LIBS) $(SDL_LIBS) ../../lib/libv4l2/.libs/libv4l2.a ../../lib/libv4lconvert/.libs/libv4lconvert.a
+sdlcam_CFLAGS = -I../..
+v4l2gl_LDADD =
+
mc_nextgen_test_CFLAGS = $(LIBUDEV_CFLAGS)
mc_nextgen_test_LDFLAGS = $(LIBUDEV_LIBS)
diff --git a/contrib/test/sdlcam.c b/contrib/test/sdlcam.c
new file mode 100644
index 0000000..16d1bef
--- /dev/null
+++ b/contrib/test/sdlcam.c
@@ -0,0 +1,1093 @@
+/*
+ Digital still camera.
+
+ SDL based, suitable for camera phone such as Nokia N900. In
+ particular, we support focus, gain and exposure control, but not
+ aperture control or lens zoom.
+
+ Copyright 2017 Pavel Machek, LGPLv2 or later.
+*/
+
+#include <time.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <jpeglib.h>
+
+#include "libv4l2.h"
+#include <linux/videodev2.h>
+#include "libv4l-plugin.h"
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_image.h>
+
+static double dtime(void)
+{
+ static double start = 0.0;
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+
+ double n = now.tv_sec + now.tv_usec / 1000000.;
+ if (!start)
+ start = n;
+ return n - start;
+}
+
+static long v4l2_g_ctrl(int fd, long id)
+{
+ int res;
+ struct v4l2_control ctrl;
+ ctrl.id = id;
+ res = v4l2_ioctl(fd, VIDIOC_G_CTRL, &ctrl);
+ if (res < 0)
+ printf("Get control %ld failed\n", id);
+ return ctrl.value;
+}
+
+static int v4l2_s_ctrl(int fd, long id, long value)
+{
+ int res;
+ struct v4l2_control ctrl;
+ ctrl.id = id;
+ ctrl.value = value;
+ res = v4l2_ioctl(fd, VIDIOC_S_CTRL, &ctrl);
+ if (res < 0)
+ printf("Set control %lx %ld failed\n", id, value);
+ return res;
+}
+
+
+static int v4l2_set_focus(int fd, int diopt)
+{
+ if (v4l2_s_ctrl(fd, V4L2_CID_FOCUS_ABSOLUTE, diopt) < 0) {
+ printf("Could not set focus\n");
+ }
+ return 0;
+}
+
+#define SIZE 1296*984*3
+struct dev_info {
+ int fd;
+ struct v4l2_format fmt;
+
+ unsigned char buf[SIZE];
+ int debug;
+#define D_TIMING 1
+};
+
+struct sdl {
+ SDL_Window *window;
+ SDL_Surface *screen, *liveview;
+
+ int wx, wy; /* Window size */
+ int sx, sy; /* Live view size */
+ int bx, by; /* Border size */
+ int nx, ny; /* Number of buttons */
+ int factor;
+
+ /* These should go separately */
+ int do_focus, do_exposure, do_flash, do_white;
+ double focus_min;
+
+ int fd;
+
+ struct dev_info *dev;
+};
+
+typedef struct {
+ uint8_t r, g, b, alpha;
+} pixel;
+
+#define d_raw 1
+
+static void sfc_put_pixel(SDL_Surface* liveview, int x, int y, pixel *p)
+{
+ Uint32* p_liveview = (Uint32*)liveview->pixels;
+ p_liveview += y*liveview->w+x;
+ *p_liveview = SDL_MapRGBA(liveview->format, p->r, p->g, p->b, p->alpha);
+}
+
+static void sdl_begin_paint(struct sdl *m)
+{
+ /* Fill the surface white */
+ SDL_FillRect(m->liveview, NULL, SDL_MapRGB( m->liveview->format, 0, 0, 0 ));
+
+ SDL_LockSurface(m->liveview);
+}
+
+static void sdl_finish_paint(struct sdl *m) {
+ SDL_UnlockSurface(m->liveview);
+ SDL_Rect rcDest = { m->bx, m->by, m->sx, m->sy };
+
+ SDL_BlitSurface(m->liveview, NULL, m->screen, &rcDest);
+ SDL_UpdateWindowSurfaceRects(m->window, &rcDest, 1);
+}
+
+static void sdl_paint_image(struct sdl *m, char **xpm, int x, int y) {
+ SDL_Surface *image = IMG_ReadXPMFromArray(xpm);
+ if (!image) {
+ printf("IMG_Load: %s\n", IMG_GetError());
+ exit(1);
+ }
+
+ int x_pos = x - image->w/2, y_pos = y - image->h/2;
+
+ SDL_Rect rcDest = { x_pos, y_pos, image->w, image->h };
+ int r = SDL_BlitSurface ( image, NULL, m->screen, &rcDest );
+
+ if (r) {
+ printf("Error blitting: %s\n", SDL_GetError());
+ exit(1);
+ }
+ SDL_FreeSurface ( image );
+}
+
+static void cam_exposure_limits(struct sdl *m, struct v4l2_queryctrl *qctrl)
+{
+ qctrl->id = V4L2_CID_EXPOSURE_ABSOLUTE;
+
+ if (v4l2_ioctl(m->fd, VIDIOC_QUERYCTRL, qctrl)) {
+ printf("Exposure absolute limits failed\n");
+ exit(1);
+ }
+
+ if (qctrl->minimum < 500)
+ qctrl->minimum = 500;
+}
+
+static void cam_set_exposure(struct sdl *m, double v)
+{
+ int cid = V4L2_CID_EXPOSURE_ABSOLUTE;
+ double res;
+ double range;
+ struct v4l2_queryctrl qctrl = { .id = cid };
+ struct v4l2_control ctrl = { .id = cid };
+
+ cam_exposure_limits(m, &qctrl);
+
+ if (v4l2_ioctl(m->fd, VIDIOC_G_CTRL, &ctrl)) {
+ printf("Can't get exposure parameters\n");
+ exit(1);
+ }
+
+ range = log2(qctrl.maximum) - log2(qctrl.minimum);
+ res = log2(qctrl.minimum) + v*range;
+ res = exp2(res);
+
+ v4l2_s_ctrl(m->fd, V4L2_CID_EXPOSURE_ABSOLUTE, res);
+}
+
+static double cam_convert_exposure(struct sdl *m, int v)
+{
+ int cid = V4L2_CID_EXPOSURE_ABSOLUTE;
+ double res;
+ struct v4l2_queryctrl qctrl = { .id = cid };
+
+ cam_exposure_limits(m, &qctrl);
+ res = (log2(v) - log2(qctrl.minimum)) / (log2(qctrl.maximum) - log2(qctrl.minimum));
+
+ return res;
+}
+
+static double cam_get_exposure(struct sdl *m)
+{
+ int cid = V4L2_CID_EXPOSURE_ABSOLUTE;
+ struct v4l2_control ctrl = { .id = cid };
+
+ if (v4l2_ioctl(m->fd, VIDIOC_G_CTRL, &ctrl))
+ return -1;
+
+ return cam_convert_exposure(m, ctrl.value);
+}
+
+static void cam_set_focus(struct sdl *m, double val)
+{
+ v4l2_s_ctrl(m->fd, V4L2_CID_FOCUS_ABSOLUTE, (val * m->focus_min) * (1023. / 20));
+}
+
+static double cam_convert_focus(struct sdl *m, double diopter)
+{
+ return diopter / m->focus_min;
+}
+
+static double cam_get_focus_diopter(struct sdl *m)
+{
+ return (v4l2_g_ctrl(m->fd, V4L2_CID_FOCUS_ABSOLUTE) * 20.) / 1023.;
+}
+
+static double cam_get_focus(struct sdl *m)
+{
+ return cam_convert_focus(m, cam_get_focus_diopter(m));
+}
+
+static void sdl_line_color(struct sdl *m, int x1, int y1, int x2, int y2, Uint32 color)
+{
+ SDL_Rect rcDest = { x1, y1, x2-x1+1, y2-y1+1};
+
+ SDL_FillRect(m->screen, &rcDest, color);
+}
+
+static void sdl_line(struct sdl *m, int x1, int y1, int x2, int y2)
+{
+ sdl_line_color(m, x1, y1, x2, y2, SDL_MapRGB( m->liveview->format, 255, 255, 255 ));
+}
+
+static void sdl_digit(struct sdl *m, int x, int y, int s, int i)
+{
+ unsigned char gr[] = { 0x5f, 0x0a, 0x76, 0x7a, 0x2b,
+ 0x79, 0x7d, 0x1a, 0x7f, 0x7b };
+ unsigned char g = gr[i];
+ /*
+ 10
+ 01 02
+ 20
+ 04 08
+ 40
+ */
+
+ if (g & 1) sdl_line(m, x, y, x, y+s);
+ if (g & 2) sdl_line(m, x+s, y, x+s, y+s);
+ if (g & 4) sdl_line(m, x, y+s, x, y+s+s);
+ if (g & 8) sdl_line(m, x+s, y+s, x+s, y+s+s);
+
+ if (g & 0x10) sdl_line(m, x, y, x+s, y);
+ if (g & 0x20) sdl_line(m, x, y+s, x+s, y+s);
+ if (g & 0x40) sdl_line(m, x, y+s+s, x+s, y+s+s);
+}
+
+static void sdl_number(struct sdl *m, int x, int y, int s, int digits, int i)
+{
+ int tot = s * 5;
+ x += tot * digits;
+ for (int j=0; j<digits; j++) {
+ sdl_digit(m, x+2, y+4, s*3, i%10);
+ i /= 10;
+ x -= tot;
+ }
+}
+
+static void sdl_paint_ui_iso(struct sdl *m, double y_, int i)
+{
+ static char *iso_xpm[] = {
+ "16 12 2 1",
+ "x c #ffffff",
+ ". c #000000",
+ "................",
+ "................",
+ "................",
+ ".x..xx..x.......",
+ ".x.x...x.x......",
+ ".x..x..x.x......",
+ ".x...x.x.x......",
+ ".x.xx...x.......",
+ "................",
+ "................",
+ "................",
+ "................",
+ };
+
+ int x = m->bx - 10;
+ int y = m->by+m->sy*y_;
+
+ sdl_number(m, x-35, y-10, 1, 3, i);
+ sdl_paint_image(m, iso_xpm, x, y);
+}
+
+static void sdl_paint_ui_exposure(struct sdl *m, int t)
+{
+ static char *time_1_xpm[] = {
+ "16 12 2 1",
+ "x c #ffffff",
+ ". c #000000",
+ "......x.........",
+ ".....x..........",
+ "....x...........",
+ "...x............",
+ "................",
+ ".xxx.xxxx.xxxx..",
+ "x....x....x.....",
+ ".xx..xxx..x.....",
+ "...x.x....x.....",
+ "...x.x....x.....",
+ "xxx..xxxx.xxxx..",
+ "................",
+ };
+ int x = m->wx-m->bx + 30;
+ int y = m->by+m->sy*cam_convert_exposure(m, 1000000/t);
+
+ sdl_number(m, x-35, y-10, 1, 3, t);
+ sdl_paint_image(m, time_1_xpm, x, y);
+}
+
+static void sdl_paint_boolean(struct sdl *m, char **image, int x, int y, int yes)
+{
+ static char *not_xpm[] = {
+ "16 12 2 1",
+ "x c #ffffff",
+ ". c #000000",
+ "......xxxxx.....",
+ "....xx.....xx...",
+ "...x.........x..",
+ "..x........xx.x.",
+ "..x......xx...x.",
+ ".x.....xx......x",
+ ".x...xx........x",
+ "..xxx.........x.",
+ "..x...........x.",
+ "...x.........x..",
+ "....xx.....xx...",
+ "......xxxxx.....",
+ };
+
+ sdl_paint_image(m, image, x, y);
+ if (!yes)
+ sdl_paint_image(m, not_xpm, 16+x, y);
+}
+
+static void sdl_paint_button(struct sdl *m, char **image, int x, int y, int yes)
+{
+ int bsx = m->wx/m->nx;
+ int bsy = m->wy/m->ny;
+ if (x < 0)
+ x += m->nx;
+ if (y < 0)
+ y += m->ny;
+ x = bsx/2 + x*bsx;
+ y = bsy/2 + y*bsy;
+ sdl_paint_boolean(m, image, x, y, yes);
+}
+
+static void sdl_paint_ui_focus(struct sdl *m, int f)
+{
+ static char *cm_xpm[] = {
+ "16 9 2 1",
+ "# c #ffffff",
+ ". c #000000",
+ "................",
+ "................",
+ "................",
+ "....###..#.#.##.",
+ "...#.....##.#..#",
+ "...#.....#..#..#",
+ "...#.....#..#..#",
+ "....###..#..#..#",
+ "................",
+ };
+ double dioptr = 1/(f/100.);
+ int x = m->bx+cam_convert_focus(m, dioptr)*m->sx;
+ int y = m->by - 20;
+
+ if (dioptr > m->focus_min)
+ return;
+ sdl_paint_image(m, cm_xpm, x, y);
+ sdl_number(m, x-12, y-15, 1, 3, f);
+}
+
+static void sdl_paint_ui(struct sdl *m)
+{
+ static char *wait_xpm[] = {
+ "16 9 2 1",
+ "# c #ffffff",
+ ". c #000000",
+ "....########....",
+ ".....#....#.....",
+ ".....#....#.....",
+ "......#..#......",
+ ".......##.......",
+ "......#..#......",
+ ".....#....#.....",
+ ".....#....#.....",
+ "....########....",
+ };
+
+ static char *ok_xpm[] = {
+ "16 9 2 1",
+ "# c #ffffff",
+ ". c #000000",
+ "...............#",
+ "............###.",
+ "..........##....",
+ "#.......##......",
+ ".#.....#........",
+ "..#...#.........",
+ "..#..#..........",
+ "...##...........",
+ "...#............",
+ };
+
+ static char *exit_xpm[] = {
+ "16 9 2 1",
+ "x c #ffffff",
+ ". c #000000",
+ "....x......x....",
+ ".....x....x.....",
+ "......x..x......",
+ ".......xx.......",
+ ".......xx.......",
+ "......x..x......",
+ ".....x....x.....",
+ "....x......x....",
+ "................",
+ };
+
+ static char *af_xpm[] = {
+ "16 12 2 1",
+ "x c #ffffff",
+ ". c #000000",
+ "................",
+ "................",
+ ".....xxxxxxx....",
+ ".....x..........",
+ ".....x..........",
+ ".x...xxxxx......",
+ "x.x..x..........",
+ "xxx..x..........",
+ "x.x..x..........",
+ "x.x..x..........",
+ "................",
+ "................",
+ };
+
+ static char *ae_xpm[] = {
+ "16 12 2 1",
+ "x c #ffffff",
+ ". c #000000",
+ "................",
+ "................",
+ ".....xxxxxxx....",
+ ".....x..........",
+ ".....x..........",
+ ".x...xxxxx......",
+ "x.x..x..........",
+ "xxx..x..........",
+ "x.x..x..........",
+ "x.x..xxxxxxx....",
+ "................",
+ "................",
+ };
+
+ static char *focus_xpm[] = {
+ "16 12 2 1",
+ "# c #ffffff",
+ ". c #000000",
+ "................",
+ "................",
+ "###..........###",
+ "#..............#",
+ "#.....####.....#",
+ ".....#....#.....",
+ ".....#....#.....",
+ "#.....####.....#",
+ "#..............#",
+ "###..........###",
+ "................",
+ "................",
+ };
+
+ static char *flash_xpm[] = {
+ "16 12 2 1",
+ "# c #ffffff",
+ ". c #000000",
+ "................",
+ "..........#.....",
+ "........##......",
+ ".......##.......",
+ "......##........",
+ ".....########...",
+ "..........##....",
+ ".......#.##.....",
+ ".......###......",
+ ".......####.....",
+ "................",
+ "................",
+ };
+
+ static char *wb_xpm[] = {
+ "16 12 2 1",
+ "# c #ffffff",
+ ". c #000000",
+ "................",
+ "................",
+ "................",
+ "#.....#..####...",
+ "#.....#..#...#..",
+ "#..#..#..####...",
+ "#..#..#..#...#..",
+ ".##.##...####...",
+ "................",
+ "................",
+ "................",
+ "................",
+ };
+/* Template for more xpm's:
+ static char *empty_xpm[] = {
+ "16 12 2 1",
+ "# c #ffffff",
+ ". c #000000",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ "................",
+ };
+*/
+ SDL_FillRect(m->screen, NULL, SDL_MapRGB( m->liveview->format, 0, 0, 0 ));
+
+ {
+ /* Paint grid */
+ int x, y;
+ int nx = m->nx;
+ for (x=1; x<nx; x++) {
+ int x_ = (x*m->wx)/nx;
+ sdl_line_color(m, x_, 1, x_, m->wy-1, SDL_MapRGB( m->liveview->format, 40, 40, 40 ));
+ }
+
+ int ny = m->ny;
+ for (y=1; y<nx; y++) {
+ int y_ = (y*m->wy)/ny;
+ sdl_line_color(m, 1, y_, m->wx-1, y_, SDL_MapRGB( m->liveview->format, 40, 40, 40 ));
+ }
+
+ }
+
+ sdl_paint_image(m, wait_xpm, m->wx/2, m->wy/2);
+
+ sdl_paint_ui_focus(m, 100);
+ sdl_paint_ui_focus(m, 40);
+ sdl_paint_ui_focus(m, 25);
+ sdl_paint_ui_focus(m, 16);
+ sdl_paint_ui_focus(m, 10);
+ sdl_paint_ui_focus(m, 8);
+ sdl_paint_ui_focus(m, 6);
+
+ sdl_paint_button(m, af_xpm, 0, 0, m->do_focus);
+ sdl_paint_button(m, ae_xpm, -1, 0, m->do_exposure);
+
+ sdl_paint_button(m, exit_xpm, 0, -1, 1);
+ sdl_paint_button(m, flash_xpm, 1, -1, m->do_flash);
+ sdl_paint_button(m, wb_xpm, 2, -1, m->do_white);
+ sdl_paint_button(m, focus_xpm, -2, -1, 1);
+ sdl_paint_button(m, ok_xpm, -1, -1, 1);
+
+ sdl_paint_ui_exposure(m, 10);
+ sdl_paint_ui_exposure(m, 100);
+ sdl_paint_ui_exposure(m, 999);
+
+ sdl_paint_ui_iso(m, 0/4., 100);
+ sdl_paint_ui_iso(m, 1/4., 200);
+ sdl_paint_ui_iso(m, 2/4., 400);
+ sdl_paint_ui_iso(m, 3/4., 800);
+
+ SDL_UpdateWindowSurface(m->window);
+}
+
+static double usec_to_time(double v)
+{
+ return 1/(v*.000001);
+}
+
+static void sdl_status(struct sdl *m, double avg)
+{
+ int ox = m->bx;
+ int oy = m->by+m->sy;
+ SDL_Rect rcDest = { ox, oy, m->sx, 25 /* m->by */ };
+
+ SDL_FillRect(m->screen, &rcDest, SDL_MapRGB( m->liveview->format, 30, 30, 30 ));
+ ox+=40;
+ sdl_number(m, ox, oy, 2, 3, avg*1000);
+
+ {
+ double focus, gain, exposure;
+
+ exposure = v4l2_g_ctrl(m->fd, V4L2_CID_EXPOSURE_ABSOLUTE);
+ gain = v4l2_g_ctrl(m->fd, 0x00980913);
+ focus = cam_get_focus_diopter(m);
+
+ ox+=40;
+ double x = usec_to_time(exposure);
+ if (x > 999) x = 999;
+ sdl_number(m, ox, oy, 2, 3, x);
+
+ ox+=40;
+ x = (gain / 10);
+ sdl_number(m, ox, oy, 2, 1, x);
+
+ ox+=20;
+ x = focus; /* diopters */
+ if (x == 0)
+ x = 999;
+ else
+ x = 100/x; /* centimeters */
+ sdl_number(m, ox, oy, 2, 3, x);
+ }
+
+ SDL_UpdateWindowSurfaceRects(m->window, &rcDest, 1);
+}
+
+static void fmt_print(struct v4l2_format *fmt)
+{
+ int f;
+ printf("Format: %dx%d. ", fmt->fmt.pix.width, fmt->fmt.pix.height);
+ printf("%x ", fmt->fmt.pix.pixelformat);
+ f = fmt->fmt.pix.pixelformat;
+ for (int i=0; i<4; i++) {
+ printf("%c", f & 0xff);
+ f >>= 8;
+ }
+ printf("\n");
+}
+
+static pixel buf_pixel(struct v4l2_format *fmt, unsigned char *buf, int x, int y)
+{
+ pixel p = { 0, 0, 0, 0 };
+ int pos = x + y*fmt->fmt.pix.width;
+
+ p.alpha = 128;
+
+ switch (fmt->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_SGRBG10:
+ {
+ short *b2 = (void *)buf;
+ x &= ~1;
+ y &= ~1;
+ p.g = b2[x + y*fmt->fmt.pix.width] /4;
+ p.r = b2[x + y*fmt->fmt.pix.width+1] /4;
+ p.b = b2[x + (y+1)*fmt->fmt.pix.width] /4;
+ }
+ break;
+
+ case V4L2_PIX_FMT_RGB24:
+ pos *= 3;
+ p.r = buf[pos];
+ p.g = buf[pos+1];
+ p.b = buf[pos+2];
+ break;
+
+ default:
+ printf("Wrong pixel format!\n");
+ fmt_print(fmt);
+ exit(1);
+ }
+
+ return p;
+}
+
+static char *fmt_name(struct v4l2_format *fmt)
+{
+ switch (fmt->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_SGRBG10:
+ return "GRBG10";
+ case V4L2_PIX_FMT_RGB24:
+ return "RGB24";
+ default:
+ return "unknown";
+ }
+}
+
+static void sdl_handle_focus(struct sdl *m, float how)
+{
+ v4l2_set_control(m->fd, V4L2_CID_FOCUS_ABSOLUTE, 65535. * how);
+}
+
+static void sdl_key(struct sdl *m, int c)
+{
+ switch (c) {
+ case 27: exit(1); break;
+ case 'q': sdl_handle_focus(m, 0.); break;
+ case 'w': sdl_handle_focus(m, 1/6.); break;
+ case 'e': sdl_handle_focus(m, 1/3.); break;
+ case 'r': sdl_handle_focus(m, 1/2.); break;
+ case 't': sdl_handle_focus(m, 1/1); break;
+ case 'y': sdl_handle_focus(m, 1/.8); break;
+ case 'u': sdl_handle_focus(m, 1/.5); break;
+ case 'i': sdl_handle_focus(m, 1/.2); break;
+ case 'o': sdl_handle_focus(m, 1/.1); break;
+ case 'p': sdl_handle_focus(m, 1/.05); break;
+ case SDLK_SPACE: /* save_image(); */ printf("Should save jpeg.\n"); break;
+ default: printf("Unknown key %d / %c", c, c);
+ }
+}
+
+static int render_statistics(struct sdl *m)
+{
+ pixel white;
+ double focus, gain, exposure;
+
+ white.r = (Uint8)0xff;
+ white.g = (Uint8)0xff;
+ white.b = (Uint8)0xff;
+ white.alpha = (Uint8)128;
+
+ exposure = cam_get_exposure(m);
+ gain = v4l2_get_control(m->fd, 0x00980913) / 65535.;
+ focus = cam_get_focus(m);
+
+ for (int x=0; x<m->sx && x<m->sx*focus; x++)
+ sfc_put_pixel(m->liveview, x, 0, &white);
+
+ for (int y=0; y<m->sy && y<m->sy*gain; y++)
+ sfc_put_pixel(m->liveview, 0, y, &white);
+
+ for (int y=0; y<m->sy && y<m->sy*exposure; y++)
+ sfc_put_pixel(m->liveview, m->sx-1, y, &white);
+
+ for (int x=0; x<m->sx; x++)
+ sfc_put_pixel(m->liveview, x, m->sy-1, &white);
+
+ return 0;
+}
+
+static void sdl_render(struct sdl *m, unsigned char *buf, struct v4l2_format *fmt)
+{
+ if (!m->window)
+ return;
+ sdl_begin_paint(m);
+
+ for (int y = 0; y < m->sy; y++)
+ for (int x = 0; x < m->sx; x++) {
+ pixel p = buf_pixel(fmt, buf, x*m->factor, y*m->factor);
+ p.alpha = 128;
+ sfc_put_pixel(m->liveview, x, y, &p);
+ }
+
+ render_statistics(m);
+ sdl_finish_paint(m);
+}
+
+static void sdl_sync_settings(struct sdl *m)
+{
+ printf("Autofocus: "); v4l2_s_ctrl(m->fd, V4L2_CID_FOCUS_AUTO, m->do_focus);
+ printf("Autogain: " ); v4l2_s_ctrl(m->fd, V4L2_CID_AUTOGAIN, m->do_exposure);
+ printf("Autowhite: "); v4l2_s_ctrl(m->fd, V4L2_CID_AUTO_WHITE_BALANCE, m->do_white);
+ v4l2_s_ctrl(m->fd, 0x009c0901, m->do_flash ? 2 : 0);
+}
+
+static void sdl_init(struct sdl *m, struct dev_info *dev, int _factor)
+{
+ m->fd = dev->fd;
+ m->dev = dev;
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ printf("Could not init SDL\n");
+ exit(1);
+ }
+
+ atexit(SDL_Quit);
+
+ m->wx = 800;
+ m->wy = 429;
+
+ m->window = SDL_CreateWindow("Camera", SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED, m->wx, m->wy,
+ SDL_WINDOW_SHOWN);
+ if (m->window == NULL) {
+ printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
+ exit(1);
+ }
+
+ m->screen = SDL_GetWindowSurface(m->window);
+ if (!m->screen) {
+ printf("Couldn't create screen\n");
+ exit(1);
+ }
+
+ m->sx = dev->fmt.fmt.pix.width;
+ m->sy = dev->fmt.fmt.pix.height;
+ m->factor = _factor;
+
+ m->sx /= m->factor;
+ m->sy /= m->factor;
+
+ m->bx = (m->wx-m->sx)/2;
+ m->by = (m->wy-m->sy)/2;
+
+ m->nx = 6;
+ m->ny = 4;
+
+ m->liveview = SDL_CreateRGBSurface(0,m->sx,m->sy,32,0,0,0,0);
+ if (!m->liveview) {
+ printf("Couldn't create liveview\n");
+ exit(1);
+ }
+
+ m->do_flash = 1;
+ m->do_focus = 0;
+ m->do_exposure = 1;
+ m->focus_min = 5;
+ sdl_paint_ui(m);
+ sdl_sync_settings(m);
+}
+
+static struct sdl sdl;
+
+static void pgm_write(struct dev_info *dev, struct v4l2_format *fmt, unsigned char *img, char *out_name)
+{
+ FILE *fout;
+ int size = fmt->fmt.pix.width * fmt->fmt.pix.height;
+ char swapped[size*2];
+
+ fout = fopen(out_name, "w");
+ if (!fout) {
+ perror("Cannot open image");
+ exit(EXIT_FAILURE);
+ }
+ switch (fmt->fmt.pix.pixelformat) {
+ /* ?? cinfo.in_color_space = JCS_YCbCr; */
+ case V4L2_PIX_FMT_SGRBG10:
+ printf("ok\n");
+ break;
+ default:
+ printf("Bad pixel format\n");
+ exit(1);
+ }
+
+ for (int i=0; i<size*2; i+=2) {
+ swapped[i] = img[i+1];
+ swapped[i+1] = img[i];
+ }
+
+ fprintf(fout, "P5\n# SDLcam raw image\n# ");
+ {
+ double focus, gain, exposure;
+
+ exposure = v4l2_get_control(dev->fd, V4L2_CID_EXPOSURE_ABSOLUTE) / 65536.;
+ gain = v4l2_get_control(dev->fd, 0x00980913) / 65536.;
+ focus = v4l2_get_control(dev->fd, V4L2_CID_FOCUS_ABSOLUTE) / 65536.;
+
+ fprintf(fout, "Exposure %f, gain %f, focus %f\n", exposure, gain, focus);
+ }
+ fprintf(fout, "%d %d\n1023\n",
+ fmt->fmt.pix.width, fmt->fmt.pix.height);
+ fwrite(swapped, size, 2, fout);
+ fclose(fout);
+}
+
+static void any_write(struct dev_info *dev)
+{
+ char name[1024];
+ unsigned char *buf;
+ time_t t = time(NULL);
+
+ buf = dev->buf;
+
+ if (1) {
+ sprintf(name, "/data/tmp/delme_%d.%s", (int) t, "pgm");
+
+ if (dev->fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_SGRBG10)
+ printf("Not in bayer10, can't write raw.\n");
+ else
+ pgm_write(dev, &dev->fmt, buf, name);
+ }
+}
+
+static void sdl_mouse(struct sdl *m, SDL_Event event)
+{
+ int ax = 0, ay = 0;
+ int nx = event.button.x / (m->wx/m->nx), ny = event.button.y / (m->wy/m->ny);
+ if (nx > m->nx/2)
+ nx -= m->nx;
+ if (ny > m->ny/2)
+ ny -= m->ny;
+
+ printf("Button %d %d\n", nx, ny);
+ switch (ny) {
+ case 0:
+ switch (nx) {
+ case 0:
+ m->do_focus ^= 1;
+ sdl_paint_ui(m);
+ sdl_sync_settings(m);
+ return;
+ case -1:
+ m->do_exposure ^= 1;
+ sdl_paint_ui(m);
+ sdl_sync_settings(m);
+ return;
+ }
+ break;
+ case -1:
+ switch (nx) {
+ case 0:
+ exit(0);
+ case 1:
+ m->do_flash ^= 1;
+ sdl_paint_ui(m);
+ sdl_sync_settings(m);
+ return;
+ case 2:
+ m->do_white ^= 1;
+ sdl_paint_ui(m);
+ sdl_sync_settings(m);
+ return;
+ case -2:
+ v4l2_s_ctrl(m->fd, V4L2_CID_AUTO_FOCUS_STATUS, 1);
+ return;
+ case -1:
+ sdl_paint_ui(m);
+ any_write(m->dev);
+ return;
+ }
+ break;
+ }
+
+ if (event.button.x > m->wx-m->bx)
+ ax = 1;
+ if (event.button.x < m->bx)
+ ax = -1;
+
+ if (event.button.y > m->wy-m->by)
+ ay = 1;
+ if (event.button.y < m->by)
+ ay = -1;
+
+ printf("mouse button at...%d, %d area %d, %d\n", event.button.x, event.button.y,
+ ax, ay);
+
+ int bx = event.button.x - m->bx;
+ int by = event.button.y - m->by;
+
+ /*
+ AF | Focus | Aexp
+ -------------------------------
+ ISO | | time
+ -------------------------------
+ Quit |Fl | nF|F!| Shoot
+ */
+ if ((ax == 0) && (ay == -1)) {
+ cam_set_focus(m, ((float) bx)/m->sx);
+ return;
+ }
+ if ((ax == -1) && (ay == 0)) {
+ m->do_exposure = 0;
+ v4l2_set_control(m->fd, 0x00980913, (65536 * by)/m->sy);
+ sdl_sync_settings(m);
+ return;
+ }
+ if ((ax == 1) && (ay == 0)) {
+ m->do_exposure = 0;
+ cam_set_exposure(m, ((double) by)/m->sy);
+ sdl_sync_settings(m);
+ return;
+ }
+ if ((ax == 0) && (ay == 1)) {
+ /* Below */
+ }
+}
+
+static void sdl_iteration(struct sdl *m)
+{
+ SDL_Event event;
+
+ while(SDL_PollEvent(&event)) {
+ switch(event.type) {
+ case SDL_QUIT:
+ exit(1);
+ break;
+ case SDL_KEYDOWN:
+ printf("key pressed... %c\n", event.key.keysym.sym);
+ /* SDLK_A, SDLK_LEFT, SDLK_RETURN, SDLK_BACKSPACE, SDLK_SPACE */
+ switch (event.key.keysym.sym) {
+ default: sdl_key(m, event.key.keysym.sym);
+ }
+ break;
+ case SDL_WINDOWEVENT:
+ if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
+ sdl_paint_ui(m);
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ sdl_mouse(m, event);
+ break;
+ }
+ }
+}
+
+static void cam_open(struct dev_info *dev)
+{
+ struct v4l2_format *fmt = &dev->fmt;
+
+ dev->fd = v4l2_open("/dev/video0", O_RDWR);
+
+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_SGRBG10;
+ fmt->fmt.pix.field = V4L2_FIELD_NONE;
+ fmt->fmt.pix.width = 1296;
+ fmt->fmt.pix.height = 984;
+
+ v4l2_s_ctrl(dev->fd, V4L2_CID_AUTO_FOCUS_STATUS, 0);
+ v4l2_set_focus(dev->fd, 50);
+
+ printf("ioctl = %d\n", v4l2_ioctl(dev->fd, VIDIOC_S_FMT, fmt));
+
+ printf("capture is %lx %s %d x %d\n", (unsigned long) fmt->fmt.pix.pixelformat, fmt_name(fmt), fmt->fmt.pix.width, fmt->fmt.pix.height);
+}
+
+/* ------------------------------------------------------------------ */
+
+
+static struct dev_info dev;
+
+int main(void)
+{
+ int i;
+ struct v4l2_format *fmt = &dev.fmt;
+
+ dtime();
+ cam_open(&dev);
+
+ sdl_init(&sdl, &dev, 5);
+
+ double loop = dtime(), max = 0, avg = .200;
+ if (dev.debug & D_TIMING)
+ printf("startup took %f\n", loop);
+
+ for (i=0; i<500000; i++) {
+ int num = v4l2_read(dev.fd, dev.buf, SIZE);
+ if (num < 0)
+ return 1;
+
+ {
+ double d = dtime();
+ sdl_render(&sdl, dev.buf, fmt);
+ if (dev.debug & D_TIMING)
+ printf("Render took %f\n", dtime() - d);
+ }
+ {
+ double d = dtime();
+ for (int i = 0; i<1; i++)
+ sdl_status(&sdl, avg);
+ if (dev.debug & D_TIMING)
+ printf("Status took %f\n", dtime() - d);
+ }
+
+ sdl_iteration(&sdl);
+ double now = dtime();
+ if (now - loop > max)
+ max = now - loop;
+ double c = 0.03;
+ avg = (now - loop) * c + avg * (1-c);
+ if (dev.debug & D_TIMING)
+ printf("Iteration %f, maximum %f, average %f\n", now-loop, max, avg);
+ loop = now;
+ }
+ return 0;
+}
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
next prev parent reply other threads:[~2017-05-21 10:33 UTC|newest]
Thread overview: 152+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-14 12:20 [PATCH v3 0/2] v4l: Add camera voice coil lens control class, current control Sakari Ailus
2017-02-14 12:20 ` [PATCH v3 1/2] " Sakari Ailus
2017-02-14 22:47 ` Pavel Machek
2017-02-15 7:15 ` Sakari Ailus
2017-02-15 8:09 ` Pavel Machek
2017-02-20 22:26 ` Sakari Ailus
2017-02-20 22:48 ` Pavel Machek
2017-04-15 2:23 ` Mauro Carvalho Chehab
2017-04-15 7:12 ` Pavel Machek
2017-04-16 9:12 ` Sakari Ailus
2017-04-19 13:51 ` Mauro Carvalho Chehab
2017-04-24 9:30 ` support autofocus / autogain in libv4l2 Pavel Machek
2017-04-24 13:38 ` Mauro Carvalho Chehab
2017-04-24 13:38 ` Mauro Carvalho Chehab
2017-04-24 21:29 ` Pavel Machek
2017-04-24 21:29 ` Pavel Machek
2017-04-25 1:47 ` Mauro Carvalho Chehab
2017-04-25 1:47 ` Mauro Carvalho Chehab
2017-04-25 8:05 ` Pavel Machek
2017-04-25 8:05 ` Pavel Machek
2017-04-25 8:08 ` Pali Rohár
2017-04-25 8:08 ` Pali Rohár
2017-04-25 8:08 ` Pali Rohár
2017-04-25 11:23 ` Pavel Machek
2017-04-25 11:23 ` Pavel Machek
2017-04-25 11:30 ` Pali Rohár
2017-04-25 11:30 ` Pali Rohár
2017-04-25 12:28 ` Pavel Machek
2017-04-25 12:28 ` Pavel Machek
2017-04-25 12:51 ` Pali Rohár
2017-04-25 12:51 ` Pali Rohár
2017-04-25 16:55 ` Nicolas Dufresne
2017-04-25 16:55 ` Nicolas Dufresne
2017-04-25 16:51 ` Nicolas Dufresne
2017-04-25 16:51 ` Nicolas Dufresne
2017-04-25 16:53 ` Nicolas Dufresne
2017-04-25 16:53 ` Nicolas Dufresne
2017-04-25 16:53 ` Nicolas Dufresne
2017-04-26 10:53 ` Pavel Machek
2017-04-26 10:53 ` Pavel Machek
2017-04-26 10:53 ` [patch] propagating controls in libv4l2 was " Pavel Machek
2017-04-26 10:53 ` Pavel Machek
2017-04-26 11:13 ` Mauro Carvalho Chehab
2017-04-26 11:13 ` Mauro Carvalho Chehab
2017-04-26 13:23 ` [patch] autogain support for bayer10 format (was Re: [patch] propagating controls in libv4l2) Pavel Machek
2017-04-26 13:23 ` Pavel Machek
2017-04-26 15:43 ` Ivaylo Dimitrov
2017-04-26 15:43 ` Ivaylo Dimitrov
2017-04-26 22:51 ` Pavel Machek
2017-04-26 22:51 ` Pavel Machek
2017-04-26 22:51 ` Pavel Machek
2017-04-27 5:52 ` Ivaylo Dimitrov
2017-04-27 5:52 ` Ivaylo Dimitrov
2017-07-13 7:57 ` Pavel Machek
2017-07-13 7:57 ` Pavel Machek
2017-05-03 19:05 ` Russell King - ARM Linux
2017-05-03 19:05 ` Russell King - ARM Linux
2017-05-03 19:58 ` Pavel Machek
2017-05-03 19:58 ` Pavel Machek
2017-05-08 22:28 ` [patch, libv4l]: fix integer overflow Pavel Machek
2017-05-09 6:29 ` Hans Verkuil
2017-05-09 6:32 ` Hans Verkuil
2017-05-09 8:02 ` Pavel Machek
2017-05-09 10:59 ` [patch, libv4l]: fix typos Pavel Machek
2017-05-09 11:01 ` [patch, libv4l]: Add support for GRBG10 format conversion Pavel Machek
2017-05-09 11:04 ` [patch, libv4l]: Introduce define for lookup table size Pavel Machek
2017-05-16 11:17 ` Hans Verkuil
2017-05-16 12:45 ` Pavel Machek
2017-05-16 12:56 ` Hans Verkuil
2017-05-16 23:23 ` Pavel Machek
2017-05-19 9:13 ` [libv4l]: How to do 10-bit support? Stand-alone conversions? Pavel Machek
2018-03-16 20:55 ` [RFC, libv4l]: Make libv4l2 usable on devices with complex pipeline Pavel Machek
2018-03-19 9:47 ` Hans Verkuil
2018-03-19 10:23 ` Pavel Machek
2018-03-19 10:47 ` Mauro Carvalho Chehab
2018-03-19 11:11 ` Hans Verkuil
2018-03-19 12:00 ` Pavel Machek
2018-03-19 12:15 ` Hans Verkuil
2018-03-19 12:48 ` Pavel Machek
2018-03-19 13:29 ` Hans Verkuil
2018-03-19 22:18 ` Pavel Machek
2018-03-19 13:45 ` Mauro Carvalho Chehab
2018-03-19 13:26 ` Mauro Carvalho Chehab
2018-03-20 7:50 ` Pavel Machek
2018-05-15 20:01 ` Pavel Machek
2018-05-15 22:03 ` Mauro Carvalho Chehab
2018-05-16 20:53 ` Pavel Machek
2018-06-02 21:01 ` Pavel Machek
2018-06-06 6:18 ` Tomasz Figa
2018-06-06 8:46 ` Pavel Machek
2018-06-06 8:53 ` Tomasz Figa
2018-06-06 10:01 ` Pavel Machek
2018-06-06 16:57 ` Mauro Carvalho Chehab
2018-06-06 21:27 ` Pavel Machek
2018-06-07 12:22 ` [PATCH, " Pavel Machek
2018-06-06 10:51 ` [RFC, " Pavel Machek
2018-06-06 11:16 ` Tomasz Figa
2018-06-06 20:37 ` Pavel Machek
2018-06-06 17:13 ` Mauro Carvalho Chehab
2018-06-06 10:23 ` Pavel Machek
2018-06-07 7:25 ` Pavel Machek
2017-05-09 11:10 ` [patch, libv4l]: fix integer overflow Pavel Machek
2017-05-16 10:42 ` Pavel Machek
2017-05-21 10:33 ` Pavel Machek [this message]
2017-05-26 20:41 ` [patch, libv4l]: add sdlcam example for testing digital still camera functionality Pavel Machek
2017-05-27 9:27 ` Hans Verkuil
2017-05-29 6:13 ` Hans Verkuil
2017-05-29 7:32 ` Pavel Machek
2017-05-29 8:02 ` Hans Verkuil
2017-06-14 11:16 ` Sakari Ailus
2017-06-14 20:41 ` Pavel Machek
2017-07-13 8:36 ` Pavel Machek
2017-05-09 8:07 ` [patch, libv4l]: fix integer overflow Pavel Machek
2017-04-30 22:48 ` [patch] autogain support for bayer10 format (was Re: [patch] propagating controls in libv4l2) Pavel Machek
2017-04-30 22:48 ` Pavel Machek
2017-07-13 9:49 ` [patch] propagating controls in libv4l2 was Re: support autofocus / autogain in libv4l2 Pavel Machek
2017-07-13 9:49 ` Pavel Machek
2017-04-26 11:26 ` Mauro Carvalho Chehab
2017-04-26 11:26 ` Mauro Carvalho Chehab
2017-04-29 9:19 ` Pavel Machek
2017-04-29 9:19 ` Pavel Machek
2017-10-21 22:00 ` Camera support, Prague next week, sdlcam Pavel Machek
2017-10-22 7:36 ` Hans Verkuil
2017-10-22 7:36 ` Hans Verkuil
2017-10-22 8:31 ` Pavel Machek
2017-10-22 8:31 ` Pavel Machek
2017-10-23 18:54 ` Pavel Machek
2017-10-23 18:54 ` Pavel Machek
2017-10-23 19:24 ` Hans Verkuil
2017-10-23 19:24 ` Hans Verkuil
2017-10-23 20:15 ` Sakari Ailus
2017-10-23 20:15 ` Sakari Ailus
2017-10-23 21:02 ` Mauro Carvalho Chehab
2017-10-23 21:02 ` Mauro Carvalho Chehab
2017-10-31 21:28 ` Nokia N9: fun with camera Pavel Machek
2017-11-01 6:36 ` Pavel Machek
2017-11-01 6:36 ` Pavel Machek
2017-11-01 15:32 ` Pavel Machek
2017-11-01 15:32 ` Pavel Machek
2017-04-24 22:07 ` support autofocus / autogain in libv4l2 Pavel Machek
2017-04-24 22:07 ` Pavel Machek
2017-04-25 1:57 ` Mauro Carvalho Chehab
2017-04-25 1:57 ` Mauro Carvalho Chehab
2017-04-25 8:20 ` Pavel Machek
2017-04-25 8:20 ` Pavel Machek
2017-04-25 11:23 ` Pavel Machek
2017-04-25 11:23 ` Pavel Machek
2017-04-28 22:00 ` [PATCH v3 1/2] v4l: Add camera voice coil lens control class, current control Pavel Machek
2017-04-29 1:46 ` Mauro Carvalho Chehab
2017-05-12 10:49 ` Sakari Ailus
2017-05-13 11:08 ` Pavel Machek
2017-02-14 12:20 ` [PATCH v3 2/2] ad5820: Use VOICE_COIL_CURRENT control Sakari Ailus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170521103315.GA10716@amd \
--to=pavel@ucw.cz \
--cc=hans.verkuil@cisco.com \
--cc=hverkuil@xs4all.nl \
--cc=ivo.g.dimitrov.75@gmail.com \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@s-opensource.com \
--cc=pali.rohar@gmail.com \
--cc=sakari.ailus@iki.fi \
--cc=sakari.ailus@linux.intel.com \
--cc=sre@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.